diff options
1011 files changed, 18169 insertions, 6282 deletions
diff --git a/Android.bp b/Android.bp index bd30de2c6749..8d3b4af82bc8 100644 --- a/Android.bp +++ b/Android.bp @@ -708,11 +708,9 @@ filegroup { name: "framework-services-net-module-wifi-shared-srcs", srcs: [ "core/java/android/net/DhcpResults.java", - "core/java/android/net/shared/Inet4AddressUtils.java", "core/java/android/net/shared/InetAddressUtils.java", "core/java/android/net/util/IpUtils.java", "core/java/android/util/LocalLog.java", - "core/java/com/android/internal/util/Preconditions.java", ], } @@ -1175,7 +1173,10 @@ java_library { "framework-annotations-lib", "unsupportedappusage", ], - visibility: ["//frameworks/base/wifi"], + visibility: [ + "//frameworks/base/wifi", + "//frameworks/base/services/net", + ], } filegroup { diff --git a/StubLibraries.bp b/StubLibraries.bp index 270c160dc5e9..bfc1367cceb9 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -97,9 +97,6 @@ stubs_defaults { droidstubs { name: "api-stubs-docs", defaults: ["metalava-full-api-stubs-default"], - api_filename: "public_api.txt", - private_api_filename: "private.txt", - removed_api_filename: "removed.txt", removed_dex_api_filename: "removed-dex.txt", arg_files: [ "core/res/AndroidManifest.xml", @@ -142,11 +139,6 @@ module_libs = " " + droidstubs { name: "system-api-stubs-docs", defaults: ["metalava-full-api-stubs-default"], - api_tag_name: "SYSTEM", - api_filename: "system-api.txt", - private_api_filename: "system-private.txt", - private_dex_api_filename: "system-private-dex.txt", - removed_api_filename: "system-removed.txt", removed_dex_api_filename: "system-removed-dex.txt", arg_files: [ "core/res/AndroidManifest.xml", @@ -179,9 +171,6 @@ droidstubs { droidstubs { name: "test-api-stubs-docs", defaults: ["metalava-full-api-stubs-default"], - api_tag_name: "TEST", - api_filename: "test-api.txt", - removed_api_filename: "test-removed.txt", arg_files: [ "core/res/AndroidManifest.xml", ], @@ -217,7 +206,6 @@ droidstubs { droidstubs { name: "module-lib-api", defaults: ["metalava-full-api-stubs-default"], - api_tag_name: "MODULE_LIB", arg_files: ["core/res/AndroidManifest.xml"], args: metalava_framework_docs_args + module_libs, check_api: { diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java index 6af1178b55f1..b4a7cd4de2ae 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java @@ -131,6 +131,10 @@ class BlobStoreConfig { LEASE_ACQUISITION_WAIT_DURATION_MS = properties.getLong(key, DEFAULT_LEASE_ACQUISITION_WAIT_DURATION_MS); break; + case KEY_COMMIT_COOL_OFF_DURATION_MS: + COMMIT_COOL_OFF_DURATION_MS = properties.getLong(key, + DEFAULT_COMMIT_COOL_OFF_DURATION_MS); + break; default: Slog.wtf(TAG, "Unknown key in device config properties: " + key); } @@ -149,6 +153,9 @@ class BlobStoreConfig { fout.println(String.format(dumpFormat, KEY_LEASE_ACQUISITION_WAIT_DURATION_MS, TimeUtils.formatDuration(LEASE_ACQUISITION_WAIT_DURATION_MS), TimeUtils.formatDuration(DEFAULT_LEASE_ACQUISITION_WAIT_DURATION_MS))); + fout.println(String.format(dumpFormat, KEY_COMMIT_COOL_OFF_DURATION_MS, + TimeUtils.formatDuration(COMMIT_COOL_OFF_DURATION_MS), + TimeUtils.formatDuration(DEFAULT_COMMIT_COOL_OFF_DURATION_MS))); } } diff --git a/apex/sdkextensions/derive_sdk/derive_sdk.rc b/apex/sdkextensions/derive_sdk/derive_sdk.rc index 1b667949eeaa..18f021ccadff 100644 --- a/apex/sdkextensions/derive_sdk/derive_sdk.rc +++ b/apex/sdkextensions/derive_sdk/derive_sdk.rc @@ -1,3 +1,5 @@ service derive_sdk /apex/com.android.sdkext/bin/derive_sdk + user nobody + group nobody oneshot disabled diff --git a/apex/statsd/aidl/android/os/IStatsd.aidl b/apex/statsd/aidl/android/os/IStatsd.aidl index 80308d26a430..0d3f4208a2ab 100644 --- a/apex/statsd/aidl/android/os/IStatsd.aidl +++ b/apex/statsd/aidl/android/os/IStatsd.aidl @@ -182,12 +182,6 @@ interface IStatsd { void unsetBroadcastSubscriber(long configId, long subscriberId, int callingUid); /** - * Apps can send an atom via this application breadcrumb with the specified label and state for - * this label. This allows building custom metrics and predicates. - */ - void sendAppBreadcrumbAtom(int label, int state); - - /** * Tell the stats daemon that all the pullers registered during boot have been sent. */ oneway void allPullersFromBootRegistered(); diff --git a/apex/statsd/framework/java/android/util/StatsLog.java b/apex/statsd/framework/java/android/util/StatsLog.java index 536b71a0e625..4eeae57fe195 100644 --- a/apex/statsd/framework/java/android/util/StatsLog.java +++ b/apex/statsd/framework/java/android/util/StatsLog.java @@ -25,8 +25,7 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.content.Context; import android.os.IStatsd; -import android.os.RemoteException; -import android.os.StatsFrameworkInitializer; +import android.os.Process; import android.util.proto.ProtoOutputStream; import com.android.internal.util.StatsdStatsLog; @@ -45,10 +44,6 @@ public final class StatsLog { private static final boolean DEBUG = false; private static final int EXPERIMENT_IDS_FIELD_ID = 1; - private static IStatsd sService; - - private static Object sLogLock = new Object(); - private StatsLog() { } @@ -59,26 +54,13 @@ public final class StatsLog { * @return True if the log request was sent to statsd. */ public static boolean logStart(int label) { - synchronized (sLogLock) { - try { - IStatsd service = getIStatsdLocked(); - if (service == null) { - if (DEBUG) { - Log.d(TAG, "Failed to find statsd when logging start"); - } - return false; - } - service.sendAppBreadcrumbAtom(label, - StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__START); - return true; - } catch (RemoteException e) { - sService = null; - if (DEBUG) { - Log.d(TAG, "Failed to connect to statsd when logging start"); - } - return false; - } - } + int callingUid = Process.myUid(); + StatsdStatsLog.write( + StatsdStatsLog.APP_BREADCRUMB_REPORTED, + callingUid, + label, + StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__START); + return true; } /** @@ -88,26 +70,13 @@ public final class StatsLog { * @return True if the log request was sent to statsd. */ public static boolean logStop(int label) { - synchronized (sLogLock) { - try { - IStatsd service = getIStatsdLocked(); - if (service == null) { - if (DEBUG) { - Log.d(TAG, "Failed to find statsd when logging stop"); - } - return false; - } - service.sendAppBreadcrumbAtom( - label, StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__STOP); - return true; - } catch (RemoteException e) { - sService = null; - if (DEBUG) { - Log.d(TAG, "Failed to connect to statsd when logging stop"); - } - return false; - } - } + int callingUid = Process.myUid(); + StatsdStatsLog.write( + StatsdStatsLog.APP_BREADCRUMB_REPORTED, + callingUid, + label, + StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__STOP); + return true; } /** @@ -117,26 +86,13 @@ public final class StatsLog { * @return True if the log request was sent to statsd. */ public static boolean logEvent(int label) { - synchronized (sLogLock) { - try { - IStatsd service = getIStatsdLocked(); - if (service == null) { - if (DEBUG) { - Log.d(TAG, "Failed to find statsd when logging event"); - } - return false; - } - service.sendAppBreadcrumbAtom( - label, StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED); - return true; - } catch (RemoteException e) { - sService = null; - if (DEBUG) { - Log.d(TAG, "Failed to connect to statsd when logging event"); - } - return false; - } - } + int callingUid = Process.myUid(); + StatsdStatsLog.write( + StatsdStatsLog.APP_BREADCRUMB_REPORTED, + callingUid, + label, + StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED); + return true; } /** @@ -181,17 +137,6 @@ public final class StatsLog { return true; } - private static IStatsd getIStatsdLocked() throws RemoteException { - if (sService != null) { - return sService; - } - sService = IStatsd.Stub.asInterface(StatsFrameworkInitializer - .getStatsServiceManager() - .getStatsdServiceRegisterer() - .get()); - return sService; - } - /** * Write an event to stats log using the raw format. * diff --git a/api/current.txt b/api/current.txt index 80e2d00b3e48..3f8bee9230a6 100644 --- a/api/current.txt +++ b/api/current.txt @@ -48759,12 +48759,8 @@ package android.telephony.ims { method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities); } - public class ImsRcsManager implements android.telephony.ims.RegistrationManager { - method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); - method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); + public class ImsRcsManager { method @NonNull public android.telephony.ims.RcsUceAdapter getUceAdapter(); - method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException; - method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback); field public static final String ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN = "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN"; } diff --git a/api/test-current.txt b/api/test-current.txt index 777cbc540b54..96cefe1afea4 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -505,6 +505,11 @@ package android.app { method public boolean isStatusBarExpansionDisabled(); } + public class TaskInfo { + method @NonNull public android.content.res.Configuration getConfiguration(); + method @NonNull public android.window.WindowContainerToken getToken(); + } + public class TimePickerDialog extends android.app.AlertDialog implements android.content.DialogInterface.OnClickListener android.widget.TimePicker.OnTimeChangedListener { method public android.widget.TimePicker getTimePicker(); } @@ -3082,6 +3087,7 @@ package android.provider { field public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS = "lock_screen_show_notifications"; field public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component"; field public static final String NOTIFICATION_BADGING = "notification_badging"; + field public static final String POWER_MENU_LOCKED_SHOW_CONTENT = "power_menu_locked_show_content"; field @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds"; field public static final String USER_SETUP_COMPLETE = "user_setup_complete"; field public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service"; @@ -4979,6 +4985,7 @@ package android.view.accessibility { public class AccessibilityNodeInfo implements android.os.Parcelable { method public void addChild(@NonNull android.os.IBinder); + method public long getSourceNodeId(); method public void setLeashedParent(@Nullable android.os.IBinder, int); method public static void setNumInstancesInUseCounter(java.util.concurrent.atomic.AtomicInteger); method public void writeToParcelNoRecycle(android.os.Parcel, int); @@ -5254,10 +5261,20 @@ package android.widget { package android.window { + public final class DisplayAreaInfo implements android.os.Parcelable { + ctor public DisplayAreaInfo(@NonNull android.window.WindowContainerToken, int); + method public int describeContents(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.window.DisplayAreaInfo> CREATOR; + field @NonNull public final android.content.res.Configuration configuration; + field public final int displayId; + field @NonNull public final android.window.WindowContainerToken token; + } + public class DisplayAreaOrganizer extends android.window.WindowOrganizer { ctor public DisplayAreaOrganizer(); - method public void onDisplayAreaAppeared(@NonNull android.window.WindowContainerToken); - method public void onDisplayAreaVanished(@NonNull android.window.WindowContainerToken); + method public void onDisplayAreaAppeared(@NonNull android.window.DisplayAreaInfo); + method public void onDisplayAreaVanished(@NonNull android.window.DisplayAreaInfo); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void registerOrganizer(int); field public static final int FEATURE_DEFAULT_TASK_CONTAINER = 1; // 0x1 field public static final int FEATURE_ROOT = 0; // 0x0 diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index acd9ec3be210..f30ed17c392f 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -104,7 +104,7 @@ cc_defaults { "src/subscriber/IncidentdReporter.cpp", "src/subscriber/SubscriberReporter.cpp", "src/uid_data.proto", - "src/utils/NamedLatch.cpp", + "src/utils/MultiConditionTrigger.cpp", ], local_include_dirs: [ @@ -295,7 +295,12 @@ cc_test { //TODO(b/153588990): Remove when the build system properly separates //32bit and 64bit architectures. - compile_multilib: "prefer32", + compile_multilib: "both", + multilib: { + lib64: { + suffix: "64", + } + }, cflags: [ "-Wall", @@ -366,7 +371,7 @@ cc_test { "tests/StatsService_test.cpp", "tests/storage/StorageManager_test.cpp", "tests/UidMap_test.cpp", - "tests/utils/NamedLatch_test.cpp", + "tests/utils/MultiConditionTrigger_test.cpp", ], static_libs: [ diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp index cfc1de49e259..c9ccfb93c86d 100644 --- a/cmds/statsd/src/FieldValue.cpp +++ b/cmds/statsd/src/FieldValue.cpp @@ -18,7 +18,6 @@ #include "Log.h" #include "FieldValue.h" #include "HashableDimensionKey.h" -#include "atoms_info.h" #include "math.h" namespace android { diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h index ba4cf11b84f1..fd86e3683970 100644 --- a/cmds/statsd/src/FieldValue.h +++ b/cmds/statsd/src/FieldValue.h @@ -27,7 +27,6 @@ struct Matcher; struct Field; struct FieldValue; -const int32_t kAttributionField = 1; const int32_t kMaxLogDepth = 2; const int32_t kLastBitMask = 0x80; const int32_t kClearLastBitDeco = 0x7f; diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index f91c6002bf5e..60e259be9558 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -25,7 +25,6 @@ #include <frameworks/base/cmds/statsd/src/experiment_ids.pb.h> #include "android-base/stringprintf.h" -#include "atoms_info.h" #include "external/StatsPullerManager.h" #include "guardrail/StatsdStats.h" #include "logd/LogEvent.h" @@ -139,14 +138,13 @@ void StatsLogProcessor::onPeriodicAlarmFired( } void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const { - if (event->getAttributionChainIndex() != -1) { - for (auto& value : *(event->getMutableValues())) { - if (value.mField.getPosAtDepth(0) > kAttributionField) { - break; - } - if (isAttributionUidField(value)) { - const int hostUid = mUidMap->getHostUidOrSelf(value.mValue.int_value); - value.mValue.setInt(hostUid); + if (std::pair<int, int> indexRange; event->hasAttributionChain(&indexRange)) { + vector<FieldValue>* const fieldValues = event->getMutableValues(); + for (int i = indexRange.first; i <= indexRange.second; i++) { + FieldValue& fieldValue = fieldValues->at(i); + if (isAttributionUidField(fieldValue)) { + const int hostUid = mUidMap->getHostUidOrSelf(fieldValue.mValue.int_value); + fieldValue.mValue.setInt(hostUid); } } } else { @@ -1055,8 +1053,8 @@ int64_t StatsLogProcessor::getLastReportTimeNs(const ConfigKey& key) { void StatsLogProcessor::notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid, const int64_t version) { std::lock_guard<std::mutex> lock(mMetricsMutex); - ALOGW("Received app upgrade"); - for (auto it : mMetricsManagers) { + VLOG("Received app upgrade"); + for (const auto& it : mMetricsManagers) { it.second->notifyAppUpgrade(eventTimeNs, apk, uid, version); } } @@ -1064,20 +1062,28 @@ void StatsLogProcessor::notifyAppUpgrade(const int64_t& eventTimeNs, const strin void StatsLogProcessor::notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid) { std::lock_guard<std::mutex> lock(mMetricsMutex); - ALOGW("Received app removed"); - for (auto it : mMetricsManagers) { + VLOG("Received app removed"); + for (const auto& it : mMetricsManagers) { it.second->notifyAppRemoved(eventTimeNs, apk, uid); } } void StatsLogProcessor::onUidMapReceived(const int64_t& eventTimeNs) { std::lock_guard<std::mutex> lock(mMetricsMutex); - ALOGW("Received uid map"); - for (auto it : mMetricsManagers) { + VLOG("Received uid map"); + for (const auto& it : mMetricsManagers) { it.second->onUidMapReceived(eventTimeNs); } } +void StatsLogProcessor::onStatsdInitCompleted(const int64_t& elapsedTimeNs) { + std::lock_guard<std::mutex> lock(mMetricsMutex); + VLOG("Received boot completed signal"); + for (const auto& it : mMetricsManagers) { + it.second->onStatsdInitCompleted(elapsedTimeNs); + } +} + void StatsLogProcessor::noteOnDiskData(const ConfigKey& key) { std::lock_guard<std::mutex> lock(mMetricsMutex); mOnDiskDataConfigs.insert(key); diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h index 97512ed7595c..ffd83ba978f4 100644 --- a/cmds/statsd/src/StatsLogProcessor.h +++ b/cmds/statsd/src/StatsLogProcessor.h @@ -120,6 +120,11 @@ public: /* Notify all MetricsManagers of uid map snapshots received */ void onUidMapReceived(const int64_t& eventTimeNs) override; + /* Notify all metrics managers of boot completed + * This will force a bucket split when the boot is finished. + */ + void onStatsdInitCompleted(const int64_t& elapsedTimeNs); + // Reset all configs. void resetConfigs(); diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index ae7a8d0d30cc..bd9f7a59fcbd 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -118,7 +118,8 @@ StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQ } })), mEventQueue(queue), - mBootCompleteLatch({kBootCompleteTag, kUidMapReceivedTag, kAllPullersRegisteredTag}), + mBootCompleteTrigger({kBootCompleteTag, kUidMapReceivedTag, kAllPullersRegisteredTag}, + [this]() { mProcessor->onStatsdInitCompleted(getElapsedRealtimeNs()); }), mStatsCompanionServiceDeathRecipient( AIBinder_DeathRecipient_new(StatsService::statsCompanionServiceDied)) { mUidMap = UidMap::getInstance(); @@ -165,12 +166,6 @@ StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQ std::thread pushedEventThread([this] { readLogs(); }); pushedEventThread.detach(); } - - std::thread bootCompletedThread([this] { - mBootCompleteLatch.wait(); - VLOG("In the boot completed thread"); - }); - bootCompletedThread.detach(); } StatsService::~StatsService() { @@ -946,7 +941,7 @@ Status StatsService::informAllUidData(const ScopedFileDescriptor& fd) { packageNames, installers); - mBootCompleteLatch.countDown(kUidMapReceivedTag); + mBootCompleteTrigger.markComplete(kUidMapReceivedTag); VLOG("StatsService::informAllUidData UidData proto parsed successfully."); return Status::ok(); } @@ -1066,7 +1061,7 @@ Status StatsService::bootCompleted() { ENFORCE_UID(AID_SYSTEM); VLOG("StatsService::bootCompleted was called"); - mBootCompleteLatch.countDown(kBootCompleteTag); + mBootCompleteTrigger.markComplete(kBootCompleteTag); return Status::ok(); } @@ -1222,20 +1217,11 @@ Status StatsService::unsetBroadcastSubscriber(int64_t configId, return Status::ok(); } -Status StatsService::sendAppBreadcrumbAtom(int32_t label, int32_t state) { - // Permission check not necessary as it's meant for applications to write to - // statsd. - android::os::statsd::util::stats_write(android::os::statsd::util::APP_BREADCRUMB_REPORTED, - (int32_t) AIBinder_getCallingUid(), label, - state); - return Status::ok(); -} - Status StatsService::allPullersFromBootRegistered() { ENFORCE_UID(AID_SYSTEM); VLOG("StatsService::allPullersFromBootRegistered was called"); - mBootCompleteLatch.countDown(kAllPullersRegisteredTag); + mBootCompleteTrigger.markComplete(kAllPullersRegisteredTag); return Status::ok(); } diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index 79324d89d8e8..b49fa1d42e66 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -33,7 +33,7 @@ #include "packages/UidMap.h" #include "shell/ShellSubscriber.h" #include "statscompanion_util.h" -#include "utils/NamedLatch.h" +#include "utils/MultiConditionTrigger.h" using namespace android; using namespace android::os; @@ -162,11 +162,6 @@ public: virtual void sayHiToStatsCompanion(); /** - * Binder call to get AppBreadcrumbReported atom. - */ - virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override; - - /** * Binder call to notify statsd that all pullers from boot have been registered. */ virtual Status allPullersFromBootRegistered(); @@ -386,7 +381,7 @@ private: mutable mutex mShellSubscriberMutex; std::shared_ptr<LogEventQueue> mEventQueue; - NamedLatch mBootCompleteLatch; + MultiConditionTrigger mBootCompleteTrigger; static const inline string kBootCompleteTag = "BOOT_COMPLETE"; static const inline string kUidMapReceivedTag = "UID_MAP"; static const inline string kAllPullersRegisteredTag = "PULLERS_REGISTERED"; @@ -399,11 +394,14 @@ private: FRIEND_TEST(StatsServiceTest, TestAddConfig_invalid); FRIEND_TEST(StatsServiceTest, TestGetUidFromArgs); FRIEND_TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp); + FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnBoot); FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade); FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval); FRIEND_TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit); + FRIEND_TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket); FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket); FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket); + FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket); FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket); FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket); }; diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 13e7ac1fd4a0..b3da32fc943f 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -46,6 +46,7 @@ import "frameworks/base/core/proto/android/stats/dnsresolver/dns_resolver.proto" import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto"; import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy_enums.proto"; import "frameworks/base/core/proto/android/stats/docsui/docsui_enums.proto"; +import "frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto"; import "frameworks/base/core/proto/android/stats/enums.proto"; import "frameworks/base/core/proto/android/stats/intelligence/enums.proto"; import "frameworks/base/core/proto/android/stats/launcher/launcher.proto"; @@ -423,6 +424,9 @@ message Atom { PackageInstallerV2Reported package_installer_v2_reported = 263 [(module) = "framework"]; UserLifecycleJourneyReported user_lifecycle_journey_reported = 264 [(module) = "framework"]; UserLifecycleEventOccurred user_lifecycle_event_occurred = 265 [(module) = "framework"]; + AccessibilityShortcutReported accessibility_shortcut_reported = + 266 [(module) = "framework"]; + AccessibilityServiceReported accessibility_service_reported = 267 [(module) = "framework"]; SdkExtensionStatus sdk_extension_status = 354; // StatsdStats tracks platform atoms with ids upto 500. @@ -8996,7 +9000,7 @@ message AppFreezeChanged { * Each pull creates multiple atoms, one for each call. The sequence is randomized when pulled. * * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/PersistPullers.java + * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java */ message VoiceCallSession { // Bearer (IMS or CS) when the call started. @@ -9060,9 +9064,7 @@ message VoiceCallSession { // See https://source.android.com/devices/tech/config/carrierid. optional int32 carrier_id = 18; - // Whether an SRVCC has been completed successfully. - // SRVCC (CS fallback) should be recorded in the IMS call since there will be no more SRVCC - // events once the call is switched to CS. + // Whether an SRVCC has been completed successfully for this call. optional bool srvcc_completed = 19; // Number of SRVCC failures. @@ -9071,7 +9073,8 @@ message VoiceCallSession { // Number of SRVCC cancellations. optional int64 srvcc_cancellation_count = 21; - // Whether the Real-Time Text (RTT) was ever used in the call. + // Whether the Real-Time Text (RTT) was ever used in the call (rather than whether RTT was + // enabled in the dialer's settings). optional bool rtt_enabled = 22; // Whether this was an emergency call. @@ -9088,7 +9091,7 @@ message VoiceCallSession { * time. The atom will be skipped if not enough data is available. * * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/PersistPullers.java + * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java */ message VoiceCallRatUsage { // Carrier ID (https://source.android.com/devices/tech/config/carrierid). @@ -9109,7 +9112,7 @@ message VoiceCallRatUsage { * Pulls the number of active SIM slots and SIMs/eSIM profiles. * * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/NonPersistPullers.java + * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java */ message SimSlotState { // Number of active SIM slots (both physical and eSIM profiles) in the device. @@ -9130,7 +9133,7 @@ message SimSlotState { * This atom reports the capabilities of the device, rather than the network it has access to. * * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/NonPersistPullers.java + * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java */ message SupportedRadioAccessFamily { // A bitmask of supported radio technologies. @@ -9441,3 +9444,38 @@ message UserLifecycleEventOccurred { } optional State state = 4; // Represents the state of an event (beginning/ending) } + +/** + * Logs when accessibility shortcut clicked. + * + * Logged from: + * frameworks/base/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java + */ +message AccessibilityShortcutReported { + // The accessibility feature(including installed a11y service, framework a11y feature, + // and installed a11y activity) package name that is assigned to the accessibility shortcut. + optional string package_name = 1; + + // The definition of the accessibility shortcut. + // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto. + optional android.stats.accessibility.ShortcutType shortcut_type = 2; + + // The definition of the service status. + // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto. + optional android.stats.accessibility.ServiceStatus service_status = 3; +} + +/** + * Logs when accessibility service status changed. + * + * Logged from: + * frameworks/base/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java + */ +message AccessibilityServiceReported { + // The accessibility service package name. + optional string package_name = 1; + + // The definition of the service status. + // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto. + optional android.stats.accessibility.ServiceStatus service_status = 2; +} diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index ebe961014336..cfd5d14b0d3b 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -252,9 +252,13 @@ void StatsPullerManager::RegisterPullUidProvider(const ConfigKey& configKey, mPullUidProviders[configKey] = provider; } -void StatsPullerManager::UnregisterPullUidProvider(const ConfigKey& configKey) { +void StatsPullerManager::UnregisterPullUidProvider(const ConfigKey& configKey, + wp<PullUidProvider> provider) { std::lock_guard<std::mutex> _l(mLock); - mPullUidProviders.erase(configKey); + const auto& it = mPullUidProviders.find(configKey); + if (it != mPullUidProviders.end() && it->second == provider) { + mPullUidProviders.erase(it); + } } void StatsPullerManager::OnAlarmFired(int64_t elapsedTimeNs) { diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h index ab0cceeb112e..5e18aaa6ed61 100644 --- a/cmds/statsd/src/external/StatsPullerManager.h +++ b/cmds/statsd/src/external/StatsPullerManager.h @@ -78,11 +78,12 @@ public: wp<PullDataReceiver> receiver); // Registers a pull uid provider for the config key. When pulling atoms, it will be used to - // determine which atoms to pull from. + // determine which uids to pull from. virtual void RegisterPullUidProvider(const ConfigKey& configKey, wp<PullUidProvider> provider); // Unregister a pull uid provider. - virtual void UnregisterPullUidProvider(const ConfigKey& configKey); + virtual void UnregisterPullUidProvider(const ConfigKey& configKey, + wp<PullUidProvider> provider); // Verify if we know how to pull for this matcher bool PullerForMatcherExists(int tagId) const; @@ -180,6 +181,8 @@ private: FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation); + + FRIEND_TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate); }; } // namespace statsd diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp index 9e72a23d27f4..aa99d0082bdd 100644 --- a/cmds/statsd/src/external/puller_util.cpp +++ b/cmds/statsd/src/external/puller_util.cpp @@ -17,7 +17,6 @@ #define DEBUG false // STOPSHIP if true #include "Log.h" -#include "atoms_info.h" #include "puller_util.h" namespace android { @@ -51,7 +50,8 @@ void mapAndMergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data, const int tagId, const vector<int>& additiveFieldsVec) { // Check the first LogEvent for attribution chain or a uid field as either all atoms with this // tagId have them or none of them do. - const bool hasAttributionChain = data[0]->getAttributionChainIndex() != -1; + std::pair<int, int> attrIndexRange; + const bool hasAttributionChain = data[0]->hasAttributionChain(&attrIndexRange); bool hasUidField = (data[0]->getUidFieldIndex() != -1); if (!hasAttributionChain && !hasUidField) { @@ -65,14 +65,13 @@ void mapAndMergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data, const ALOGE("Wrong atom. Expecting %d, got %d", tagId, event->GetTagId()); return; } - if (event->getAttributionChainIndex() != -1) { - for (auto& value : *(event->getMutableValues())) { - if (value.mField.getPosAtDepth(0) > kAttributionField) { - break; - } - if (isAttributionUidField(value)) { - const int hostUid = uidMap->getHostUidOrSelf(value.mValue.int_value); - value.mValue.setInt(hostUid); + if (hasAttributionChain) { + vector<FieldValue>* const fieldValues = event->getMutableValues(); + for (int i = attrIndexRange.first; i <= attrIndexRange.second; i++) { + FieldValue& fieldValue = fieldValues->at(i); + if (isAttributionUidField(fieldValue)) { + const int hostUid = uidMap->getHostUidOrSelf(fieldValue.mValue.int_value); + fieldValue.mValue.setInt(hostUid); } } } else { diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h index 21e524a9fadf..805281ccd2d2 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.h +++ b/cmds/statsd/src/guardrail/StatsdStats.h @@ -16,7 +16,6 @@ #pragma once #include "config/ConfigKey.h" -#include "atoms_info.h" #include <gtest/gtest_prod.h> #include <log/log_time.h> diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index eb830e114b40..10b1059796a0 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -211,8 +211,8 @@ void LogEvent::parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last, uint8 void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) { - int firstUidInChainIndex = mValues.size(); - int32_t numNodes = readNextValue<uint8_t>(); + const unsigned int firstUidInChainIndex = mValues.size(); + const int32_t numNodes = readNextValue<uint8_t>(); for (pos[1] = 1; pos[1] <= numNodes; pos[1]++) { last[1] = (pos[1] == numNodes); @@ -225,6 +225,11 @@ void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last, last[2] = true; parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0); } + // Check if at least one node was successfully parsed. + if (mValues.size() - 1 > firstUidInChainIndex) { + mAttributionChainStartIndex = firstUidInChainIndex; + mAttributionChainEndIndex = mValues.size() - 1; + } parseAnnotations(numAnnotations, firstUidInChainIndex); @@ -401,7 +406,6 @@ bool LogEvent::parseBuffer(uint8_t* buf, size_t len) { break; case ATTRIBUTION_CHAIN_TYPE: parseAttributionChain(pos, /*depth=*/0, last, getNumAnnotations(typeInfo)); - if (mAttributionChainIndex == -1) mAttributionChainIndex = pos[0]; break; case ERROR_TYPE: mErrorBitmask = readNextValue<int32_t>(); @@ -567,6 +571,19 @@ void LogEvent::ToProto(ProtoOutputStream& protoOutput) const { writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput); } +bool LogEvent::hasAttributionChain(std::pair<int, int>* indexRange) const { + if (mAttributionChainStartIndex == -1 || mAttributionChainEndIndex == -1) { + return false; + } + + if (nullptr != indexRange) { + indexRange->first = mAttributionChainStartIndex; + indexRange->second = mAttributionChainEndIndex; + } + + return true; +} + void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut) { ProtoOutputStream proto; diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h index dedcfaf6cd87..731b9661067a 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -163,12 +163,10 @@ public: return mUidFieldIndex; } - // Returns the index of (the first) attribution chain within the atom - // definition. Note that the value is 1-indexed. If there is no attribution - // chain, returns -1. - inline int getAttributionChainIndex() { - return mAttributionChainIndex; - } + // Returns whether this LogEvent has an AttributionChain. + // If it does and indexRange is not a nullptr, populate indexRange with the start and end index + // of the AttributionChain within mValues. + bool hasAttributionChain(std::pair<int, int>* indexRange = nullptr) const; // Returns the index of the exclusive state field within the FieldValues vector if // an exclusive state exists. If there is no exclusive state field, returns -1. @@ -324,7 +322,8 @@ private: // Annotations bool mTruncateTimestamp = false; int mUidFieldIndex = -1; - int mAttributionChainIndex = -1; + int mAttributionChainStartIndex = -1; + int mAttributionChainEndIndex = -1; int mExclusiveStateFieldIndex = -1; int mResetState = -1; }; diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h index a4711e8357f2..f9a8842efc3d 100644 --- a/cmds/statsd/src/metrics/CountMetricProducer.h +++ b/cmds/statsd/src/metrics/CountMetricProducer.h @@ -109,10 +109,11 @@ private: FRIEND_TEST(CountMetricProducerTest, TestEventsWithNonSlicedCondition); FRIEND_TEST(CountMetricProducerTest, TestEventsWithSlicedCondition); FRIEND_TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced); - FRIEND_TEST(CountMetricProducerTest, TestEventWithAppUpgrade); - FRIEND_TEST(CountMetricProducerTest, TestEventWithAppUpgradeInNextBucket); FRIEND_TEST(CountMetricProducerTest, TestFirstBucket); FRIEND_TEST(CountMetricProducerTest, TestOneWeekTimeUnit); + + FRIEND_TEST(CountMetricProducerTest_PartialBucket, TestSplitInCurrentBucket); + FRIEND_TEST(CountMetricProducerTest_PartialBucket, TestSplitInNextBucket); }; } // namespace statsd diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h index cc48f99add01..6f84076ee6b5 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.h +++ b/cmds/statsd/src/metrics/DurationMetricProducer.h @@ -154,12 +154,14 @@ private: FRIEND_TEST(DurationMetricTrackerTest, TestNoCondition); FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedCondition); FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState); - FRIEND_TEST(DurationMetricTrackerTest, TestSumDurationWithUpgrade); - FRIEND_TEST(DurationMetricTrackerTest, TestSumDurationWithUpgradeInFollowingBucket); - FRIEND_TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgrade); - FRIEND_TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgradeInNextBucket); FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicates); FRIEND_TEST(DurationMetricTrackerTest, TestFirstBucket); + + FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestSumDuration); + FRIEND_TEST(DurationMetricProducerTest_PartialBucket, + TestSumDurationWithSplitInFollowingBucket); + FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDuration); + FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDurationWithSplitInNextBucket); }; } // namespace statsd diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h index aa0cae26080d..2eb584b097ea 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.h +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h @@ -73,18 +73,23 @@ public: bool pullSuccess, int64_t originalPullTimeNs) override; // GaugeMetric needs to immediately trigger another pull when we create the partial bucket. - void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid, - const int64_t version) override { + void notifyAppUpgrade(const int64_t& eventTimeNs) override { std::lock_guard<std::mutex> lock(mMutex); if (!mSplitBucketForAppUpgrade) { return; } - if (eventTimeNs > getCurrentBucketEndTimeNs()) { - // Flush full buckets on the normal path up to the latest bucket boundary. - flushIfNeededLocked(eventTimeNs); + flushLocked(eventTimeNs); + if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) { + pullAndMatchEventsLocked(eventTimeNs); } - flushCurrentBucketLocked(eventTimeNs, eventTimeNs); + }; + + // GaugeMetric needs to immediately trigger another pull when we create the partial bucket. + void onStatsdInitCompleted(const int64_t& eventTimeNs) override { + std::lock_guard<std::mutex> lock(mMutex); + + flushLocked(eventTimeNs); if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) { pullAndMatchEventsLocked(eventTimeNs); } @@ -190,13 +195,14 @@ private: FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition); FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition); FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition); - FRIEND_TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade); - FRIEND_TEST(GaugeMetricProducerTest, TestPulledWithUpgrade); FRIEND_TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled); FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection); FRIEND_TEST(GaugeMetricProducerTest, TestFirstBucket); FRIEND_TEST(GaugeMetricProducerTest, TestPullOnTrigger); FRIEND_TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput); + + FRIEND_TEST(GaugeMetricProducerTest_PartialBucket, TestPushedEvents); + FRIEND_TEST(GaugeMetricProducerTest_PartialBucket, TestPulled); }; } // namespace statsd diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h index 6aba13ca7859..91c98ea27269 100644 --- a/cmds/statsd/src/metrics/MetricProducer.h +++ b/cmds/statsd/src/metrics/MetricProducer.h @@ -141,30 +141,25 @@ public: } /** - * Forces this metric to split into a partial bucket right now. If we're past a full bucket, we - * first call the standard flushing code to flush up to the latest full bucket. Then we call - * the flush again when the end timestamp is forced to be now, and then after flushing, update - * the start timestamp to be now. + * Force a partial bucket split on app upgrade */ - virtual void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid, - const int64_t version) { + virtual void notifyAppUpgrade(const int64_t& eventTimeNs) { std::lock_guard<std::mutex> lock(mMutex); - - if (eventTimeNs > getCurrentBucketEndTimeNs()) { - // Flush full buckets on the normal path up to the latest bucket boundary. - flushIfNeededLocked(eventTimeNs); - } - // Now flush a partial bucket. - flushCurrentBucketLocked(eventTimeNs, eventTimeNs); - // Don't update the current bucket number so that the anomaly tracker knows this bucket - // is a partial bucket and can merge it with the previous bucket. + flushLocked(eventTimeNs); }; - void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid) { + void notifyAppRemoved(const int64_t& eventTimeNs) { // Force buckets to split on removal also. - notifyAppUpgrade(eventTimeNs, apk, uid, 0); + notifyAppUpgrade(eventTimeNs); }; + /** + * Force a partial bucket split on boot complete. + */ + virtual void onStatsdInitCompleted(const int64_t& eventTimeNs) { + std::lock_guard<std::mutex> lock(mMutex); + flushLocked(eventTimeNs); + } // Consume the parsed stats log entry that already matched the "what" of the metric. void onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) { std::lock_guard<std::mutex> lock(mMutex); @@ -292,8 +287,7 @@ public: // End: getters/setters protected: /** - * Flushes the current bucket if the eventTime is after the current bucket's end time. This will - also flush the current partial bucket in memory. + * Flushes the current bucket if the eventTime is after the current bucket's end time. */ virtual void flushIfNeededLocked(const int64_t& eventTime){}; diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index d832ed86580d..d7ad27bd9134 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -189,7 +189,7 @@ MetricsManager::~MetricsManager() { StateManager::getInstance().unregisterListener(atomId, it); } } - mPullerManager->UnregisterPullUidProvider(mConfigKey); + mPullerManager->UnregisterPullUidProvider(mConfigKey, this); VLOG("~MetricsManager()"); } @@ -231,8 +231,8 @@ bool MetricsManager::isConfigValid() const { void MetricsManager::notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid, const int64_t version) { // Inform all metric producers. - for (auto it : mAllMetricProducers) { - it->notifyAppUpgrade(eventTimeNs, apk, uid, version); + for (const auto& it : mAllMetricProducers) { + it->notifyAppUpgrade(eventTimeNs); } // check if we care this package if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) != mAllowedPkg.end()) { @@ -252,8 +252,8 @@ void MetricsManager::notifyAppUpgrade(const int64_t& eventTimeNs, const string& void MetricsManager::notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid) { // Inform all metric producers. - for (auto it : mAllMetricProducers) { - it->notifyAppRemoved(eventTimeNs, apk, uid); + for (const auto& it : mAllMetricProducers) { + it->notifyAppRemoved(eventTimeNs); } // check if we care this package if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) != mAllowedPkg.end()) { @@ -282,6 +282,13 @@ void MetricsManager::onUidMapReceived(const int64_t& eventTimeNs) { initLogSourceWhiteList(); } +void MetricsManager::onStatsdInitCompleted(const int64_t& eventTimeNs) { + // Inform all metric producers. + for (const auto& it : mAllMetricProducers) { + it->onStatsdInitCompleted(eventTimeNs); + } +} + void MetricsManager::init() { for (const auto& producer : mAllMetricProducers) { producer->prepareFirstBucket(); @@ -380,11 +387,14 @@ bool MetricsManager::eventSanityCheck(const LogEvent& event) { // Uid is 3rd from last field and must match the caller's uid, // unless that caller is statsd itself (statsd is allowed to spoof uids). long appHookUid = event.GetLong(event.size()-2, &err); - if (err != NO_ERROR ) { + if (err != NO_ERROR) { VLOG("APP_BREADCRUMB_REPORTED had error when parsing the uid"); return false; } - int32_t loggerUid = event.GetUid(); + + // Because the uid within the LogEvent may have been mapped from + // isolated to host, map the loggerUid similarly before comparing. + int32_t loggerUid = mUidMap->getHostUidOrSelf(event.GetUid()); if (loggerUid != appHookUid && loggerUid != AID_STATSD) { VLOG("APP_BREADCRUMB_REPORTED has invalid uid: claimed %ld but caller is %d", appHookUid, loggerUid); @@ -393,7 +403,7 @@ bool MetricsManager::eventSanityCheck(const LogEvent& event) { // The state must be from 0,3. This part of code must be manually updated. long appHookState = event.GetLong(event.size(), &err); - if (err != NO_ERROR ) { + if (err != NO_ERROR) { VLOG("APP_BREADCRUMB_REPORTED had error when parsing the state field"); return false; } else if (appHookState < 0 || appHookState > 3) { @@ -407,7 +417,7 @@ bool MetricsManager::eventSanityCheck(const LogEvent& event) { // Uid is the first field provided. long jankUid = event.GetLong(1, &err); - if (err != NO_ERROR ) { + if (err != NO_ERROR) { VLOG("Davey occurred had error when parsing the uid"); return false; } @@ -419,7 +429,7 @@ bool MetricsManager::eventSanityCheck(const LogEvent& event) { } long duration = event.GetLong(event.size(), &err); - if (err != NO_ERROR ) { + if (err != NO_ERROR) { VLOG("Davey occurred had error when parsing the duration"); return false; } else if (duration > 100000) { diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index 1fd6572cc760..ef03d2064ab0 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -70,6 +70,8 @@ public: void onUidMapReceived(const int64_t& eventTimeNs); + void onStatsdInitCompleted(const int64_t& elapsedTimeNs); + void init(); vector<int32_t> getPullAtomUids(int32_t atomId) override; diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h index e9273dc54424..c8dc8cc290c4 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.h +++ b/cmds/statsd/src/metrics/ValueMetricProducer.h @@ -69,8 +69,7 @@ public: bool pullSuccess, int64_t originalPullTimeNs) override; // ValueMetric needs special logic if it's a pulled atom. - void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid, - const int64_t version) override { + void notifyAppUpgrade(const int64_t& eventTimeNs) override { std::lock_guard<std::mutex> lock(mMutex); if (!mSplitBucketForAppUpgrade) { return; @@ -81,6 +80,15 @@ public: flushCurrentBucketLocked(eventTimeNs, eventTimeNs); }; + // ValueMetric needs special logic if it's a pulled atom. + void onStatsdInitCompleted(const int64_t& eventTimeNs) override { + std::lock_guard<std::mutex> lock(mMutex); + if (mIsPulled && mCondition) { + pullAndMatchEventsLocked(eventTimeNs); + } + flushCurrentBucketLocked(eventTimeNs, eventTimeNs); + }; + void onStateChanged(int64_t eventTimeNs, int32_t atomId, const HashableDimensionKey& primaryKey, int oldState, int newState) override; @@ -256,7 +264,6 @@ private: FRIEND_TEST(ValueMetricProducerTest, TestAnomalyDetection); FRIEND_TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange); - FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundariesOnAppUpgrade); FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange); FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition); FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition); @@ -269,10 +276,8 @@ private: FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled); FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition); FRIEND_TEST(ValueMetricProducerTest, TestFirstBucket); - FRIEND_TEST(ValueMetricProducerTest, TestFullBucketResetWhenLastBucketInvalid); FRIEND_TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff); FRIEND_TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff); - FRIEND_TEST(ValueMetricProducerTest, TestPartialBucketCreated); FRIEND_TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries); FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse); FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue); @@ -283,15 +288,12 @@ private: FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset); FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset); FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering); - FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade); - FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse); FRIEND_TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled); FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateAvg); FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateMax); FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateMin); FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateSum); FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithCondition); - FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade); FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition); FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded); FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange); @@ -313,6 +315,14 @@ private: FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit); FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWrongBucket); + + FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestBucketBoundariesOnPartialBucket); + FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestFullBucketResetWhenLastBucketInvalid); + FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPartialBucketCreated); + FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPushedEvents); + FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValue); + FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse); + friend class ValueMetricProducerTestHelper; }; diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp index 88616dde61b7..3ab44f4a06af 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp @@ -21,7 +21,6 @@ #include <inttypes.h> -#include "atoms_info.h" #include "FieldValue.h" #include "MetricProducer.h" #include "condition/CombinationConditionTracker.h" diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp index f9fddc8a7c8a..2acffee0f443 100644 --- a/cmds/statsd/src/stats_log_util.cpp +++ b/cmds/statsd/src/stats_log_util.cpp @@ -24,7 +24,6 @@ #include "statscompanion_util.h" -using android::util::AtomsInfo; using android::util::FIELD_COUNT_REPEATED; using android::util::FIELD_TYPE_BOOL; using android::util::FIELD_TYPE_FIXED64; diff --git a/cmds/statsd/src/utils/NamedLatch.cpp b/cmds/statsd/src/utils/MultiConditionTrigger.cpp index 6e77977857cc..43a69337f368 100644 --- a/cmds/statsd/src/utils/NamedLatch.cpp +++ b/cmds/statsd/src/utils/MultiConditionTrigger.cpp @@ -15,7 +15,9 @@ */ #define DEBUG false // STOPSHIP if true -#include "NamedLatch.h" +#include "MultiConditionTrigger.h" + +#include <thread> using namespace std; @@ -23,26 +25,33 @@ namespace android { namespace os { namespace statsd { -NamedLatch::NamedLatch(const set<string>& eventNames) : mRemainingEventNames(eventNames) { +MultiConditionTrigger::MultiConditionTrigger(const set<string>& conditionNames, + function<void()> trigger) + : mRemainingConditionNames(conditionNames), + mTrigger(trigger), + mCompleted(mRemainingConditionNames.empty()) { + if (mCompleted) { + thread executorThread([this] { mTrigger(); }); + executorThread.detach(); + } } -void NamedLatch::countDown(const string& eventName) { - bool notify = false; +void MultiConditionTrigger::markComplete(const string& conditionName) { + bool doTrigger = false; { lock_guard<mutex> lg(mMutex); - mRemainingEventNames.erase(eventName); - notify = mRemainingEventNames.empty(); + if (mCompleted) { + return; + } + mRemainingConditionNames.erase(conditionName); + mCompleted = mRemainingConditionNames.empty(); + doTrigger = mCompleted; } - if (notify) { - mConditionVariable.notify_all(); + if (doTrigger) { + std::thread executorThread([this] { mTrigger(); }); + executorThread.detach(); } } - -void NamedLatch::wait() const { - unique_lock<mutex> unique_lk(mMutex); - mConditionVariable.wait(unique_lk, [this] { return mRemainingEventNames.empty(); }); -} - } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/utils/MultiConditionTrigger.h b/cmds/statsd/src/utils/MultiConditionTrigger.h new file mode 100644 index 000000000000..51f6029915be --- /dev/null +++ b/cmds/statsd/src/utils/MultiConditionTrigger.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include <gtest/gtest_prod.h> + +#include <mutex> +#include <set> + +namespace android { +namespace os { +namespace statsd { + +/** + * This class provides a utility to wait for a set of named conditions to occur. + * + * It will execute the trigger runnable in a detached thread once all conditions have been marked + * true. + */ +class MultiConditionTrigger { +public: + explicit MultiConditionTrigger(const std::set<std::string>& conditionNames, + std::function<void()> trigger); + + MultiConditionTrigger(const MultiConditionTrigger&) = delete; + MultiConditionTrigger& operator=(const MultiConditionTrigger&) = delete; + + // Mark a specific condition as true. If this condition has called markComplete already or if + // the event was not specified in the constructor, the function is a no-op. + void markComplete(const std::string& eventName); + +private: + mutable std::mutex mMutex; + std::set<std::string> mRemainingConditionNames; + std::function<void()> mTrigger; + bool mCompleted; + + FRIEND_TEST(MultiConditionTriggerTest, TestCountDownCalledBySameEventName); +}; +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/utils/NamedLatch.h b/cmds/statsd/src/utils/NamedLatch.h deleted file mode 100644 index 70238370f647..000000000000 --- a/cmds/statsd/src/utils/NamedLatch.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <gtest/gtest_prod.h> - -#include <condition_variable> -#include <mutex> -#include <set> - -namespace android { -namespace os { -namespace statsd { - -/** - * This class provides a threading primitive similar to a latch. - * The primary difference is that it waits for named events to occur instead of waiting for - * N threads to reach a certain point. - * - * It uses a condition variable under the hood. - */ -class NamedLatch { -public: - explicit NamedLatch(const std::set<std::string>& eventNames); - - NamedLatch(const NamedLatch&) = delete; - NamedLatch& operator=(const NamedLatch&) = delete; - - // Mark a specific event as completed. If this event has called countDown already or if the - // event was not specified in the constructor, the function is a no-op. - void countDown(const std::string& eventName); - - // Blocks the calling thread until all events in eventNames have called countDown. - void wait() const; - -private: - mutable std::mutex mMutex; - mutable std::condition_variable mConditionVariable; - std::set<std::string> mRemainingEventNames; - - FRIEND_TEST(NamedLatchTest, TestCountDownCalledBySameEventName); -}; -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp index e52e2d024e94..00f336a4986d 100644 --- a/cmds/statsd/tests/LogEvent_test.cpp +++ b/cmds/statsd/tests/LogEvent_test.cpp @@ -95,6 +95,7 @@ TEST(LogEventTest, TestPrimitiveParsing) { EXPECT_EQ(100, logEvent.GetTagId()); EXPECT_EQ(1000, logEvent.GetUid()); EXPECT_EQ(1001, logEvent.GetPid()); + EXPECT_FALSE(logEvent.hasAttributionChain()); const vector<FieldValue>& values = logEvent.getValues(); EXPECT_EQ(4, values.size()); @@ -143,6 +144,7 @@ TEST(LogEventTest, TestStringAndByteArrayParsing) { EXPECT_EQ(100, logEvent.GetTagId()); EXPECT_EQ(1000, logEvent.GetUid()); EXPECT_EQ(1001, logEvent.GetPid()); + EXPECT_FALSE(logEvent.hasAttributionChain()); const vector<FieldValue>& values = logEvent.getValues(); EXPECT_EQ(2, values.size()); @@ -179,6 +181,7 @@ TEST(LogEventTest, TestEmptyString) { EXPECT_EQ(100, logEvent.GetTagId()); EXPECT_EQ(1000, logEvent.GetUid()); EXPECT_EQ(1001, logEvent.GetPid()); + EXPECT_FALSE(logEvent.hasAttributionChain()); const vector<FieldValue>& values = logEvent.getValues(); EXPECT_EQ(1, values.size()); @@ -248,6 +251,11 @@ TEST(LogEventTest, TestAttributionChain) { const vector<FieldValue>& values = logEvent.getValues(); EXPECT_EQ(4, values.size()); // 2 per attribution node + std::pair<int, int> attrIndexRange; + EXPECT_TRUE(logEvent.hasAttributionChain(&attrIndexRange)); + EXPECT_EQ(0, attrIndexRange.first); + EXPECT_EQ(3, attrIndexRange.second); + // Check first attribution node const FieldValue& uid1Item = values[0]; Field expectedField = getField(100, {1, 1, 1}, 2, {true, false, false}); diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp index 1075fe4f9ce1..a44541dddf53 100644 --- a/cmds/statsd/tests/MetricsManager_test.cpp +++ b/cmds/statsd/tests/MetricsManager_test.cpp @@ -528,7 +528,7 @@ TEST(MetricsManagerTest, TestLogSources) { })); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterPullUidProvider(kConfigKey, _)).Times(1); - EXPECT_CALL(*pullerManager, UnregisterPullUidProvider(kConfigKey)).Times(1); + EXPECT_CALL(*pullerManager, UnregisterPullUidProvider(kConfigKey, _)).Times(1); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp index d29394b1c5a6..b809286da5f4 100644 --- a/cmds/statsd/tests/StatsLogProcessor_test.cpp +++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp @@ -301,6 +301,29 @@ TEST(StatsLogProcessorTest, TestOnDumpReportEraseData) { EXPECT_TRUE(noData); } +TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate) { + // Setup simple config key corresponding to empty config. + sp<UidMap> m = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + sp<AlarmMonitor> anomalyAlarmMonitor; + sp<AlarmMonitor> subscriberAlarmMonitor; + StatsLogProcessor p( + m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, + [](const ConfigKey& key) { return true; }, + [](const int&, const vector<int64_t>&) { return true; }); + ConfigKey key(3, 4); + StatsdConfig config = MakeConfig(false); + p.OnConfigUpdated(0, key, config); + EXPECT_NE(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end()); + + config.add_default_pull_packages("AID_STATSD"); + p.OnConfigUpdated(5, key, config); + EXPECT_NE(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end()); + + p.OnConfigRemoved(key); + EXPECT_EQ(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end()); +} + TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) { int uid = 1111; diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp index b173ee0334a7..911762339b70 100644 --- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp @@ -89,6 +89,7 @@ StatsdConfig MakeValueMetricConfig(int64_t minTime) { valueMetric->set_bucket(FIVE_MINUTES); valueMetric->set_min_bucket_size_nanos(minTime); valueMetric->set_use_absolute_value_on_reset(true); + valueMetric->set_skip_zero_diff_output(false); return config; } @@ -217,6 +218,35 @@ TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) { EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count()); } +TEST(PartialBucketE2eTest, TestCountMetricSplitOnBoot) { + shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr); + SendConfig(service, MakeConfig()); + int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are + // initialized with. + + // Goes into the first bucket + service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + NS_PER_SEC, 100).get()); + int64_t bootCompleteTimeNs = start + 2 * NS_PER_SEC; + service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs); + // Goes into the second bucket. + service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3 * NS_PER_SEC, 100).get()); + + ConfigMetricsReport report = GetReports(service->mProcessor, start + 4 * NS_PER_SEC); + backfillStartEndTimestamp(&report); + + ASSERT_EQ(1, report.metrics_size()); + ASSERT_EQ(1, report.metrics(0).count_metrics().data_size()); + ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size()); + EXPECT_TRUE(report.metrics(0) + .count_metrics() + .data(0) + .bucket_info(0) + .has_start_bucket_elapsed_nanos()); + EXPECT_EQ(MillisToNano(NanoToMillis(bootCompleteTimeNs)), + report.metrics(0).count_metrics().data(0).bucket_info(0).end_bucket_elapsed_nanos()); + EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count()); +} + TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) { shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr); service->mPullerManager->RegisterPullAtomCallback( @@ -229,13 +259,22 @@ TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) { // initialized with. service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start); - service->mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2, - String16("v2"), String16("")); + int64_t appUpgradeTimeNs = 5 * 60 * NS_PER_SEC + start + 2 * NS_PER_SEC; + service->mUidMap->updateApp(appUpgradeTimeNs, String16(kApp1.c_str()), 1, 2, String16("v2"), + String16("")); ConfigMetricsReport report = - GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100, true); + GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC); + backfillStartEndTimestamp(&report); + EXPECT_EQ(1, report.metrics_size()); EXPECT_EQ(0, report.metrics(0).value_metrics().skipped_size()); + + // The fake subsystem state sleep puller returns two atoms. + ASSERT_EQ(2, report.metrics(0).value_metrics().data_size()); + ASSERT_EQ(2, report.metrics(0).value_metrics().data(0).bucket_info_size()); + EXPECT_EQ(MillisToNano(NanoToMillis(appUpgradeTimeNs)), + report.metrics(0).value_metrics().data(0).bucket_info(1).end_bucket_elapsed_nanos()); } TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) { @@ -249,13 +288,13 @@ TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) { int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. - const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2; + const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2 * NS_PER_SEC; service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start); service->mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"), String16("")); ConfigMetricsReport report = - GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC, true); + GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC); backfillStartEndTimestamp(&report); ASSERT_EQ(1, report.metrics_size()); @@ -264,10 +303,49 @@ TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) { // Can't test the start time since it will be based on the actual time when the pulling occurs. EXPECT_EQ(MillisToNano(NanoToMillis(endSkipped)), report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos()); + + ASSERT_EQ(2, report.metrics(0).value_metrics().data_size()); + EXPECT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size()); +} + +TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket) { + shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr); + // Initial pull will fail since puller is not registered. + SendConfig(service, MakeValueMetricConfig(0)); + int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are + // initialized with. + + service->mPullerManager->RegisterPullAtomCallback( + /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {}, + SharedRefBase::make<FakeSubsystemSleepCallback>()); + + int64_t bootCompleteTimeNs = start + NS_PER_SEC; + service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs); + + service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start); + + ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100); + backfillStartEndTimestamp(&report); + + // First bucket is dropped due to the initial pull failing + ASSERT_EQ(1, report.metrics_size()); + EXPECT_EQ(1, report.metrics(0).value_metrics().skipped_size()); + EXPECT_EQ(MillisToNano(NanoToMillis(bootCompleteTimeNs)), + report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos()); + + // The fake subsystem state sleep puller returns two atoms. + ASSERT_EQ(2, report.metrics(0).value_metrics().data_size()); + ASSERT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size()); + EXPECT_EQ( + MillisToNano(NanoToMillis(bootCompleteTimeNs)), + report.metrics(0).value_metrics().data(0).bucket_info(0).start_bucket_elapsed_nanos()); } TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) { shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr); + service->mPullerManager->RegisterPullAtomCallback( + /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {}, + SharedRefBase::make<FakeSubsystemSleepCallback>()); // Partial buckets don't occur when app is first installed. service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); SendConfig(service, MakeGaugeMetricConfig(0)); @@ -278,16 +356,22 @@ TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) { service->mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"), String16("")); - ConfigMetricsReport report = - GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100, true); - EXPECT_EQ(1, report.metrics_size()); + ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100); + backfillStartEndTimestamp(&report); + ASSERT_EQ(1, report.metrics_size()); EXPECT_EQ(0, report.metrics(0).gauge_metrics().skipped_size()); + // The fake subsystem state sleep puller returns two atoms. + ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size()); + EXPECT_EQ(2, report.metrics(0).gauge_metrics().data(0).bucket_info_size()); } TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) { shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr); // Partial buckets don't occur when app is first installed. service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); + service->mPullerManager->RegisterPullAtomCallback( + /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {}, + SharedRefBase::make<FakeSubsystemSleepCallback>()); SendConfig(service, MakeGaugeMetricConfig(60 * NS_PER_SEC /* One minute */)); int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. @@ -298,7 +382,7 @@ TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) { String16("")); ConfigMetricsReport report = - GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC, true); + GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC); backfillStartEndTimestamp(&report); ASSERT_EQ(1, report.metrics_size()); ASSERT_EQ(1, report.metrics(0).gauge_metrics().skipped_size()); @@ -306,6 +390,38 @@ TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) { EXPECT_TRUE(report.metrics(0).gauge_metrics().skipped(0).has_start_bucket_elapsed_nanos()); EXPECT_EQ(MillisToNano(NanoToMillis(endSkipped)), report.metrics(0).gauge_metrics().skipped(0).end_bucket_elapsed_nanos()); + ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size()); + EXPECT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size()); +} + +TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket) { + shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr); + // Initial pull will fail since puller hasn't been registered. + SendConfig(service, MakeGaugeMetricConfig(0)); + int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are + // initialized with. + + service->mPullerManager->RegisterPullAtomCallback( + /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {}, + SharedRefBase::make<FakeSubsystemSleepCallback>()); + + int64_t bootCompleteTimeNs = start + NS_PER_SEC; + service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs); + + service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start); + + ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100); + backfillStartEndTimestamp(&report); + + ASSERT_EQ(1, report.metrics_size()); + EXPECT_EQ(0, report.metrics(0).gauge_metrics().skipped_size()); + // The fake subsystem state sleep puller returns two atoms. + ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size()); + // No data in the first bucket, so nothing is reported + ASSERT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size()); + EXPECT_EQ( + MillisToNano(NanoToMillis(bootCompleteTimeNs)), + report.metrics(0).gauge_metrics().data(0).bucket_info(0).start_bucket_elapsed_nanos()); } #else diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp index 65f8de69711d..8131725cd148 100644 --- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp @@ -38,9 +38,9 @@ namespace android { namespace os { namespace statsd { -const ConfigKey kConfigKey(0, 12345); namespace { +const ConfigKey kConfigKey(0, 12345); void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) { AStatsEvent* statsEvent = AStatsEvent_obtain(); @@ -61,6 +61,13 @@ void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId, string ui } // namespace +// Setup for parameterized tests. +class CountMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {}; + +INSTANTIATE_TEST_SUITE_P(CountMetricProducerTest_PartialBucket, + CountMetricProducerTest_PartialBucket, + testing::Values(APP_UPGRADE, BOOT_COMPLETE)); + TEST(CountMetricProducerTest, TestFirstBucket) { CountMetric metric; metric.set_id(1); @@ -237,11 +244,11 @@ TEST(CountMetricProducerTest, TestEventsWithSlicedCondition) { EXPECT_EQ(1LL, bucketInfo.mCount); } -TEST(CountMetricProducerTest, TestEventWithAppUpgrade) { +TEST_P(CountMetricProducerTest_PartialBucket, TestSplitInCurrentBucket) { sp<AlarmMonitor> alarmMonitor; int64_t bucketStartTimeNs = 10000000000; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL; - int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC; + int64_t eventTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC; int tagId = 1; int conditionTagId = 2; @@ -260,22 +267,30 @@ TEST(CountMetricProducerTest, TestEventWithAppUpgrade) { sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor); EXPECT_TRUE(anomalyTracker != nullptr); - // Bucket is flushed yet. + // Bucket is not flushed yet. LogEvent event1(/*uid=*/0, /*pid=*/0); makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111"); countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); EXPECT_EQ(0UL, countProducer.mPastBuckets.size()); EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY)); - // App upgrade forces bucket flush. + // App upgrade or boot complete forces bucket flush. // Check that there's a past bucket and the bucket end is not adjusted. - countProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1); + switch (GetParam()) { + case APP_UPGRADE: + countProducer.notifyAppUpgrade(eventTimeNs); + break; + case BOOT_COMPLETE: + countProducer.onStatsdInitCompleted(eventTimeNs); + break; + } EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ((long long)bucketStartTimeNs, + EXPECT_EQ(bucketStartTimeNs, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs); - EXPECT_EQ((long long)eventUpgradeTimeNs, + EXPECT_EQ(eventTimeNs, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs); - EXPECT_EQ(eventUpgradeTimeNs, countProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(0, countProducer.getCurrentBucketNum()); + EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs); // Anomaly tracker only contains full buckets. EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY)); @@ -285,7 +300,8 @@ TEST(CountMetricProducerTest, TestEventWithAppUpgrade) { makeLogEvent(&event2, bucketStartTimeNs + 59 * NS_PER_SEC + 10, tagId, /*uid=*/"222"); countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2); EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ(eventUpgradeTimeNs, countProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(0, countProducer.getCurrentBucketNum()); EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY)); // Third event in following bucket. @@ -294,13 +310,14 @@ TEST(CountMetricProducerTest, TestEventWithAppUpgrade) { countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3); EXPECT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); EXPECT_EQ(lastEndTimeNs, countProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(1, countProducer.getCurrentBucketNum()); EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY)); } -TEST(CountMetricProducerTest, TestEventWithAppUpgradeInNextBucket) { +TEST_P(CountMetricProducerTest_PartialBucket, TestSplitInNextBucket) { int64_t bucketStartTimeNs = 10000000000; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL; - int64_t eventUpgradeTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC; + int64_t eventTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC; int tagId = 1; int conditionTagId = 2; @@ -319,15 +336,23 @@ TEST(CountMetricProducerTest, TestEventWithAppUpgradeInNextBucket) { countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); EXPECT_EQ(0UL, countProducer.mPastBuckets.size()); - // App upgrade forces bucket flush. - // Check that there's a past bucket and the bucket end is not adjusted. - countProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1); + // App upgrade or boot complete forces bucket flush. + // Check that there's a past bucket and the bucket end is not adjusted since the upgrade + // occurred after the bucket end time. + switch (GetParam()) { + case APP_UPGRADE: + countProducer.notifyAppUpgrade(eventTimeNs); + break; + case BOOT_COMPLETE: + countProducer.onStatsdInitCompleted(eventTimeNs); + break; + } EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ((int64_t)bucketStartTimeNs, + EXPECT_EQ(bucketStartTimeNs, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs); EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs); - EXPECT_EQ(eventUpgradeTimeNs, countProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs); // Next event occurs in same bucket as partial bucket created. LogEvent event2(/*uid=*/0, /*pid=*/0); @@ -340,7 +365,7 @@ TEST(CountMetricProducerTest, TestEventWithAppUpgradeInNextBucket) { makeLogEvent(&event3, bucketStartTimeNs + 121 * NS_PER_SEC + 10, tagId, /*uid=*/"333"); countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3); EXPECT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ((int64_t)eventUpgradeTimeNs, + EXPECT_EQ((int64_t)eventTimeNs, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketStartNs); EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketEndNs); diff --git a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp index 30f815962160..8ef251952db7 100644 --- a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp @@ -41,10 +41,10 @@ namespace android { namespace os { namespace statsd { -const ConfigKey kConfigKey(0, 12345); namespace { +const ConfigKey kConfigKey(0, 12345); void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); @@ -55,6 +55,13 @@ void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) { } // namespace +// Setup for parameterized tests. +class DurationMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {}; + +INSTANTIATE_TEST_SUITE_P(DurationMetricProducerTest_PartialBucket, + DurationMetricProducerTest_PartialBucket, + testing::Values(APP_UPGRADE, BOOT_COMPLETE)); + TEST(DurationMetricTrackerTest, TestFirstBucket) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); DurationMetric metric; @@ -205,7 +212,7 @@ TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState) { EXPECT_EQ(1LL, buckets2[0].mDuration); } -TEST(DurationMetricTrackerTest, TestSumDurationWithUpgrade) { +TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDuration) { /** * The duration starts from the first bucket, through the two partial buckets (10-70sec), * another bucket, and ends at the beginning of the next full bucket. @@ -217,15 +224,7 @@ TEST(DurationMetricTrackerTest, TestSumDurationWithUpgrade) { */ int64_t bucketStartTimeNs = 10000000000; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL; - int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC; - int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC; - int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC; - int tagId = 1; - LogEvent event1(/*uid=*/0, /*pid=*/0); - makeLogEvent(&event1, startTimeNs, tagId); - LogEvent event2(/*uid=*/0, /*pid=*/0); - makeLogEvent(&event2, endTimeNs, tagId); DurationMetric metric; metric.set_id(1); @@ -238,32 +237,47 @@ TEST(DurationMetricTrackerTest, TestSumDurationWithUpgrade) { 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs); + int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC; + LogEvent event1(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event1, startTimeNs, tagId); durationProducer.onMatchedLogEvent(1 /* start index*/, event1); EXPECT_EQ(0UL, durationProducer.mPastBuckets.size()); EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs); - durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1); + int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC; + switch (GetParam()) { + case APP_UPGRADE: + durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } EXPECT_EQ(1UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); std::vector<DurationBucket> buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY]; EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs); - EXPECT_EQ(eventUpgradeTimeNs, buckets[0].mBucketEndNs); - EXPECT_EQ(eventUpgradeTimeNs - startTimeNs, buckets[0].mDuration); - EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(partialBucketSplitTimeNs, buckets[0].mBucketEndNs); + EXPECT_EQ(partialBucketSplitTimeNs - startTimeNs, buckets[0].mDuration); + EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(0, durationProducer.getCurrentBucketNum()); // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket. + int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC; + LogEvent event2(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event2, endTimeNs, tagId); durationProducer.onMatchedLogEvent(2 /* stop index*/, event2); buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY]; EXPECT_EQ(3UL, buckets.size()); - EXPECT_EQ(eventUpgradeTimeNs, buckets[1].mBucketStartNs); + EXPECT_EQ(partialBucketSplitTimeNs, buckets[1].mBucketStartNs); EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketEndNs); - EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - eventUpgradeTimeNs, buckets[1].mDuration); + EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - partialBucketSplitTimeNs, buckets[1].mDuration); EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[2].mBucketStartNs); EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs); EXPECT_EQ(bucketSizeNs, buckets[2].mDuration); } -TEST(DurationMetricTrackerTest, TestSumDurationWithUpgradeInFollowingBucket) { +TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDurationWithSplitInFollowingBucket) { /** * Expected buckets (start at 11s, upgrade at 75s, end at 135s): * - [10,70]: 59 secs @@ -272,15 +286,7 @@ TEST(DurationMetricTrackerTest, TestSumDurationWithUpgradeInFollowingBucket) { */ int64_t bucketStartTimeNs = 10000000000; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL; - int64_t eventUpgradeTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC; - int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC; - int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC; - int tagId = 1; - LogEvent event1(/*uid=*/0, /*pid=*/0); - makeLogEvent(&event1, startTimeNs, tagId); - LogEvent event2(/*uid=*/0, /*pid=*/0); - makeLogEvent(&event2, endTimeNs, tagId); DurationMetric metric; metric.set_id(1); @@ -293,11 +299,22 @@ TEST(DurationMetricTrackerTest, TestSumDurationWithUpgradeInFollowingBucket) { 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs); + int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC; + LogEvent event1(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event1, startTimeNs, tagId); durationProducer.onMatchedLogEvent(1 /* start index*/, event1); EXPECT_EQ(0UL, durationProducer.mPastBuckets.size()); EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs); - durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1); + int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC; + switch (GetParam()) { + case APP_UPGRADE: + durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } EXPECT_EQ(2UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); std::vector<DurationBucket> buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY]; @@ -305,32 +322,29 @@ TEST(DurationMetricTrackerTest, TestSumDurationWithUpgradeInFollowingBucket) { EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs); EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs, buckets[0].mDuration); EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketStartNs); - EXPECT_EQ(eventUpgradeTimeNs, buckets[1].mBucketEndNs); - EXPECT_EQ(eventUpgradeTimeNs - (bucketStartTimeNs + bucketSizeNs), buckets[1].mDuration); - EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(partialBucketSplitTimeNs, buckets[1].mBucketEndNs); + EXPECT_EQ(partialBucketSplitTimeNs - (bucketStartTimeNs + bucketSizeNs), buckets[1].mDuration); + EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(1, durationProducer.getCurrentBucketNum()); // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket. + int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC; + LogEvent event2(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event2, endTimeNs, tagId); durationProducer.onMatchedLogEvent(2 /* stop index*/, event2); buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY]; EXPECT_EQ(3UL, buckets.size()); - EXPECT_EQ(eventUpgradeTimeNs, buckets[2].mBucketStartNs); + EXPECT_EQ(partialBucketSplitTimeNs, buckets[2].mBucketStartNs); EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs); - EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs - eventUpgradeTimeNs, buckets[2].mDuration); + EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs - partialBucketSplitTimeNs, + buckets[2].mDuration); } -TEST(DurationMetricTrackerTest, TestSumDurationAnomalyWithUpgrade) { +TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDurationAnomaly) { sp<AlarmMonitor> alarmMonitor; int64_t bucketStartTimeNs = 10000000000; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL; - int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC; - int64_t startTimeNs = bucketStartTimeNs + 1; - int64_t endTimeNs = startTimeNs + 65 * NS_PER_SEC; - int tagId = 1; - LogEvent event1(/*uid=*/0, /*pid=*/0); - makeLogEvent(&event1, startTimeNs, tagId); - LogEvent event2(/*uid=*/0, /*pid=*/0); - makeLogEvent(&event2, endTimeNs, tagId); // Setup metric with alert. DurationMetric metric; @@ -351,27 +365,35 @@ TEST(DurationMetricTrackerTest, TestSumDurationAnomalyWithUpgrade) { sp<AnomalyTracker> anomalyTracker = durationProducer.addAnomalyTracker(alert, alarmMonitor); EXPECT_TRUE(anomalyTracker != nullptr); + int64_t startTimeNs = bucketStartTimeNs + 1; + LogEvent event1(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event1, startTimeNs, tagId); durationProducer.onMatchedLogEvent(1 /* start index*/, event1); - durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1); + + int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC; + switch (GetParam()) { + case APP_UPGRADE: + durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket. + int64_t endTimeNs = startTimeNs + 65 * NS_PER_SEC; + LogEvent event2(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event2, endTimeNs, tagId); durationProducer.onMatchedLogEvent(2 /* stop index*/, event2); + EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY)); } -TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgrade) { +TEST_P(DurationMetricProducerTest_PartialBucket, TestMaxDuration) { int64_t bucketStartTimeNs = 10000000000; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL; - int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC; - int64_t startTimeNs = bucketStartTimeNs + 1; - int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC; - int tagId = 1; - LogEvent event1(/*uid=*/0, /*pid=*/0); - makeLogEvent(&event1, startTimeNs, tagId); - LogEvent event2(/*uid=*/0, /*pid=*/0); - makeLogEvent(&event2, endTimeNs, tagId); DurationMetric metric; metric.set_id(1); @@ -385,15 +407,30 @@ TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgrade) { 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs); + int64_t startTimeNs = bucketStartTimeNs + 1; + LogEvent event1(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event1, startTimeNs, tagId); durationProducer.onMatchedLogEvent(1 /* start index*/, event1); EXPECT_EQ(0UL, durationProducer.mPastBuckets.size()); EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs); - durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1); + int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC; + switch (GetParam()) { + case APP_UPGRADE: + durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(0, durationProducer.getCurrentBucketNum()); // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket. + int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC; + LogEvent event2(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event2, endTimeNs, tagId); durationProducer.onMatchedLogEvent(2 /* stop index*/, event2); EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); @@ -406,18 +443,10 @@ TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgrade) { EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration); } -TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgradeInNextBucket) { +TEST_P(DurationMetricProducerTest_PartialBucket, TestMaxDurationWithSplitInNextBucket) { int64_t bucketStartTimeNs = 10000000000; int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL; - int64_t eventUpgradeTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC; - int64_t startTimeNs = bucketStartTimeNs + 1; - int64_t endTimeNs = startTimeNs + 115 * NS_PER_SEC; - int tagId = 1; - LogEvent event1(/*uid=*/0, /*pid=*/0); - makeLogEvent(&event1, startTimeNs, tagId); - LogEvent event2(/*uid=*/0, /*pid=*/0); - makeLogEvent(&event2, endTimeNs, tagId); DurationMetric metric; metric.set_id(1); @@ -431,24 +460,39 @@ TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgradeInNextBucket) { 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs); + int64_t startTimeNs = bucketStartTimeNs + 1; + LogEvent event1(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event1, startTimeNs, tagId); durationProducer.onMatchedLogEvent(1 /* start index*/, event1); EXPECT_EQ(0UL, durationProducer.mPastBuckets.size()); EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs); - durationProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1); + int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC; + switch (GetParam()) { + case APP_UPGRADE: + durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(1, durationProducer.getCurrentBucketNum()); // Stop occurs in the same partial bucket as created for the app upgrade. + int64_t endTimeNs = startTimeNs + 115 * NS_PER_SEC; + LogEvent event2(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event2, endTimeNs, tagId); durationProducer.onMatchedLogEvent(2 /* stop index*/, event2); EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ(eventUpgradeTimeNs, durationProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs); durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1); std::vector<DurationBucket> buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY]; EXPECT_EQ(1UL, buckets.size()); - EXPECT_EQ(eventUpgradeTimeNs, buckets[0].mBucketStartNs); + EXPECT_EQ(partialBucketSplitTimeNs, buckets[0].mBucketStartNs); EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketEndNs); EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration); } diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp index 42d0d5d8c530..9d2ec88e2f9b 100644 --- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp @@ -42,6 +42,8 @@ namespace android { namespace os { namespace statsd { +namespace { + const ConfigKey kConfigKey(0, 12345); const int tagId = 1; const int64_t metricId = 123; @@ -52,9 +54,8 @@ const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000L const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs; const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs; const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs; -const int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC; +const int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC; -namespace { shared_ptr<LogEvent> makeLogEvent(int32_t atomId, int64_t timestampNs, int32_t value1, string str1, int32_t value2) { AStatsEvent* statsEvent = AStatsEvent_obtain(); @@ -71,6 +72,13 @@ shared_ptr<LogEvent> makeLogEvent(int32_t atomId, int64_t timestampNs, int32_t v } } // anonymous namespace +// Setup for parameterized tests. +class GaugeMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {}; + +INSTANTIATE_TEST_SUITE_P(GaugeMetricProducerTest_PartialBucket, + GaugeMetricProducerTest_PartialBucket, + testing::Values(APP_UPGRADE, BOOT_COMPLETE)); + /* * Tests that the first bucket works correctly */ @@ -194,7 +202,7 @@ TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) { EXPECT_EQ(25L, it->mValue.int_value); } -TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade) { +TEST_P(GaugeMetricProducerTest_PartialBucket, TestPushedEvents) { sp<AlarmMonitor> alarmMonitor; GaugeMetric metric; metric.set_id(metricId); @@ -230,11 +238,22 @@ TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade) { gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); EXPECT_EQ(1UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY)); - gaugeProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1); + switch (GetParam()) { + case APP_UPGRADE: + gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + gaugeProducer.onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } EXPECT_EQ(0UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY)); EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); + EXPECT_EQ(bucketStartTimeNs, + gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs); + EXPECT_EQ(partialBucketSplitTimeNs, + gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs); EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum); - EXPECT_EQ(eventUpgradeTimeNs, gaugeProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs); // Partial buckets are not sent to anomaly tracker. EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY)); @@ -244,7 +263,11 @@ TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade) { gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event2); EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum); EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ((int64_t)eventUpgradeTimeNs, gaugeProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(bucketStartTimeNs, + gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs); + EXPECT_EQ(partialBucketSplitTimeNs, + gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs); + EXPECT_EQ((int64_t)partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs); // Partial buckets are not sent to anomaly tracker. EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY)); @@ -267,7 +290,7 @@ TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade) { EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY)); } -TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) { +TEST_P(GaugeMetricProducerTest_PartialBucket, TestPulled) { GaugeMetric metric; metric.set_id(metricId); metric.set_bucket(ONE_MINUTE); @@ -293,7 +316,8 @@ TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) { .WillOnce(Invoke( [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) { data->clear(); - data->push_back(CreateRepeatedValueLogEvent(tagId, eventUpgradeTimeNs, 2)); + data->push_back( + CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 2)); return true; })); @@ -311,10 +335,21 @@ TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) { .mFields->begin() ->mValue.int_value); - gaugeProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1); + switch (GetParam()) { + case APP_UPGRADE: + gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + gaugeProducer.onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); + EXPECT_EQ(bucketStartTimeNs, + gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs); + EXPECT_EQ(partialBucketSplitTimeNs, + gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs); EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum); - EXPECT_EQ((int64_t)eventUpgradeTimeNs, gaugeProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs); EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size()); EXPECT_EQ(2, gaugeProducer.mCurrentSlicedBucket->begin() ->second.front() @@ -370,7 +405,7 @@ TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled) { .mFields->begin() ->mValue.int_value); - gaugeProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1); + gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs); EXPECT_EQ(0UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum); EXPECT_EQ(bucketStartTimeNs, gaugeProducer.mCurrentBucketStartTimeNs); diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp index 3b4d646f0f2f..f493cc4033ad 100644 --- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp @@ -41,6 +41,8 @@ namespace android { namespace os { namespace statsd { +namespace { + const ConfigKey kConfigKey(0, 12345); const int tagId = 1; const int64_t metricId = 123; @@ -58,10 +60,18 @@ double epsilon = 0.001; static void assertPastBucketValuesSingleKey( const std::unordered_map<MetricDimensionKey, std::vector<ValueBucket>>& mPastBuckets, const std::initializer_list<int>& expectedValuesList, - const std::initializer_list<int64_t>& expectedDurationNsList) { - std::vector<int> expectedValues(expectedValuesList); - std::vector<int64_t> expectedDurationNs(expectedDurationNsList); + const std::initializer_list<int64_t>& expectedDurationNsList, + const std::initializer_list<int64_t>& expectedStartTimeNsList, + const std::initializer_list<int64_t>& expectedEndTimeNsList) { + vector<int> expectedValues(expectedValuesList); + vector<int64_t> expectedDurationNs(expectedDurationNsList); + vector<int64_t> expectedStartTimeNs(expectedStartTimeNsList); + vector<int64_t> expectedEndTimeNs(expectedEndTimeNsList); + ASSERT_EQ(expectedValues.size(), expectedDurationNs.size()); + ASSERT_EQ(expectedValues.size(), expectedStartTimeNs.size()); + ASSERT_EQ(expectedValues.size(), expectedEndTimeNs.size()); + if (expectedValues.size() == 0) { ASSERT_EQ(0, mPastBuckets.size()); return; @@ -70,15 +80,21 @@ static void assertPastBucketValuesSingleKey( ASSERT_EQ(1, mPastBuckets.size()); ASSERT_EQ(expectedValues.size(), mPastBuckets.begin()->second.size()); - auto buckets = mPastBuckets.begin()->second; + const vector<ValueBucket>& buckets = mPastBuckets.begin()->second; for (int i = 0; i < expectedValues.size(); i++) { EXPECT_EQ(expectedValues[i], buckets[i].values[0].long_value) << "Values differ at index " << i; EXPECT_EQ(expectedDurationNs[i], buckets[i].mConditionTrueNs) << "Condition duration value differ at index " << i; + EXPECT_EQ(expectedStartTimeNs[i], buckets[i].mBucketStartNs) + << "Start time differs at index " << i; + EXPECT_EQ(expectedEndTimeNs[i], buckets[i].mBucketEndNs) + << "End time differs at index " << i; } } +} // anonymous namespace + class ValueMetricProducerTestHelper { public: static sp<ValueMetricProducer> createValueProducerNoConditions( @@ -191,6 +207,13 @@ public: } }; +// Setup for parameterized tests. +class ValueMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {}; + +INSTANTIATE_TEST_SUITE_P(ValueMetricProducerTest_PartialBucket, + ValueMetricProducerTest_PartialBucket, + testing::Values(APP_UPGRADE, BOOT_COMPLETE)); + /* * Tests that the first bucket works correctly */ @@ -325,9 +348,10 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) { EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[2].mConditionTrueNs); } -TEST(ValueMetricProducerTest, TestPartialBucketCreated) { +TEST_P(ValueMetricProducerTest_PartialBucket, TestPartialBucketCreated) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2; EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)) // Initialize bucket. .WillOnce(Invoke([](int tagId, const ConfigKey&, @@ -337,10 +361,12 @@ TEST(ValueMetricProducerTest, TestPartialBucketCreated) { return true; })) // Partial bucket. - .WillOnce(Invoke([](int tagId, const ConfigKey&, - vector<std::shared_ptr<LogEvent>>* data, bool) { + .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&, + vector<std::shared_ptr<LogEvent>>* data, + bool) { data->clear(); - data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 5)); + data->push_back( + CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs + 8, 5)); return true; })); @@ -354,19 +380,21 @@ TEST(ValueMetricProducerTest, TestPartialBucketCreated) { valueProducer->onDataPulled(allData, /** success */ true, bucket2StartTimeNs); // Partial buckets created in 2nd bucket. - valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1); + switch (GetParam()) { + case APP_UPGRADE: + valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } + EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs); + EXPECT_EQ(1, valueProducer->getCurrentBucketNum()); - // One full bucket and one partial bucket. - EXPECT_EQ(1UL, valueProducer->mPastBuckets.size()); - vector<ValueBucket> buckets = valueProducer->mPastBuckets.begin()->second; - EXPECT_EQ(2UL, buckets.size()); - // Full bucket (2 - 1) - EXPECT_EQ(1, buckets[0].values[0].long_value); - EXPECT_EQ(bucketSizeNs, buckets[0].mConditionTrueNs); - // Full bucket (5 - 3) - EXPECT_EQ(3, buckets[1].values[0].long_value); - // partial bucket [bucket2StartTimeNs, bucket2StartTimeNs + 2] - EXPECT_EQ(2, buckets[1].mConditionTrueNs); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1, 3}, + {bucketSizeNs, partialBucketSplitTimeNs - bucket2StartTimeNs}, + {bucketStartTimeNs, bucket2StartTimeNs}, + {bucket2StartTimeNs, partialBucketSplitTimeNs}); } /* @@ -613,7 +641,8 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { allData.clear(); allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110)); valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); // has one slice EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); @@ -625,7 +654,8 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { EXPECT_EQ(10, curInterval.value.long_value); valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); // has one slice EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); @@ -636,10 +666,12 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { EXPECT_EQ(false, curBaseInfo.hasBase); valueProducer->onConditionChanged(true, bucket3StartTimeNs + 1); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10, 20}, {bucketSizeNs - 8, 1}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10, 20}, {bucketSizeNs - 8, 1}, + {bucketStartTimeNs, bucket2StartTimeNs}, + {bucket2StartTimeNs, bucket3StartTimeNs}); } -TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) { +TEST_P(ValueMetricProducerTest_PartialBucket, TestPushedEvents) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); UidMap uidMap; @@ -660,25 +692,46 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) { valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); - valueProducer.notifyAppUpgrade(bucketStartTimeNs + 150, "ANY.APP", 1, 1); - EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs); + int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 150; + switch (GetParam()) { + case APP_UPGRADE: + valueProducer.notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + valueProducer.onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } + assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, + {partialBucketSplitTimeNs - bucketStartTimeNs}, + {bucketStartTimeNs}, {partialBucketSplitTimeNs}); + EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(0, valueProducer.getCurrentBucketNum()); + // Event arrives after the bucket split. LogEvent event2(/*uid=*/0, /*pid=*/0); - CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 10); + CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 20); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2); - EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs); + + assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, + {partialBucketSplitTimeNs - bucketStartTimeNs}, + {bucketStartTimeNs}, {partialBucketSplitTimeNs}); + EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(0, valueProducer.getCurrentBucketNum()); // Next value should create a new bucket. LogEvent event3(/*uid=*/0, /*pid=*/0); - CreateRepeatedValueLogEvent(&event3, tagId, bucketStartTimeNs + 65 * NS_PER_SEC, 10); + CreateRepeatedValueLogEvent(&event3, tagId, bucket2StartTimeNs + 5 * NS_PER_SEC, 10); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3); - EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); + assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10, 20}, + {partialBucketSplitTimeNs - bucketStartTimeNs, + bucket2StartTimeNs - partialBucketSplitTimeNs}, + {bucketStartTimeNs, partialBucketSplitTimeNs}, + {partialBucketSplitTimeNs, bucket2StartTimeNs}); EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, valueProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(1, valueProducer.getCurrentBucketNum()); } -TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) { +TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValue) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); UidMap uidMap; @@ -689,14 +742,16 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) { atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 150; EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)) .WillOnce(Return(true)) - .WillOnce(Invoke([](int tagId, const ConfigKey&, - vector<std::shared_ptr<LogEvent>>* data, bool) { + .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&, + vector<std::shared_ptr<LogEvent>>* data, + bool) { data->clear(); - data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 149, 120)); + data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 120)); return true; })); ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex, @@ -711,20 +766,27 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) { valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); - valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1); - EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs); - assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {150}); + switch (GetParam()) { + case APP_UPGRADE: + valueProducer.notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + valueProducer.onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } + EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs); + EXPECT_EQ(1, valueProducer.getCurrentBucketNum()); + assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {150}, {bucket2StartTimeNs}, + {partialBucketSplitTimeNs}); allData.clear(); allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 150)); valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs); - EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); EXPECT_EQ(bucket3StartTimeNs, valueProducer.mCurrentBucketStartTimeNs); - EXPECT_EQ(20L, - valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value); - assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20, 30}, - {150, bucketSizeNs - 150}); + EXPECT_EQ(2, valueProducer.getCurrentBucketNum()); + assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20, 30}, {150, bucketSizeNs - 150}, + {bucket2StartTimeNs, partialBucketSplitTimeNs}, + {partialBucketSplitTimeNs, bucket3StartTimeNs}); } TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) { @@ -754,12 +816,12 @@ TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) { valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); - valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1); + valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150); EXPECT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs); } -TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) { +TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse) { ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -784,14 +846,21 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) { valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100); EXPECT_FALSE(valueProducer->mCondition); - valueProducer->notifyAppUpgrade(bucket2StartTimeNs - 50, "ANY.APP", 1, 1); + int64_t partialBucketSplitTimeNs = bucket2StartTimeNs - 50; + switch (GetParam()) { + case APP_UPGRADE: + valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } // Expect one full buckets already done and starting a partial bucket. - EXPECT_EQ(bucket2StartTimeNs - 50, valueProducer->mCurrentBucketStartTimeNs); - EXPECT_EQ(1UL, valueProducer->mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); - EXPECT_EQ(bucketStartTimeNs, - valueProducer->mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs); + EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs); + EXPECT_EQ(0, valueProducer->getCurrentBucketNum()); assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, - {(bucket2StartTimeNs - 100) - (bucketStartTimeNs + 1)}); + {(bucket2StartTimeNs - 100) - (bucketStartTimeNs + 1)}, + {bucketStartTimeNs}, {partialBucketSplitTimeNs}); EXPECT_FALSE(valueProducer->mCondition); } TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) { @@ -834,7 +903,8 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) { EXPECT_EQ(30, curInterval.value.long_value); valueProducer.flushIfNeededLocked(bucket2StartTimeNs); - assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {30}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {30}, {bucketSizeNs}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); } TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) { @@ -895,7 +965,8 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) { EXPECT_EQ(50, curInterval.value.long_value); valueProducer.flushIfNeededLocked(bucket2StartTimeNs); - assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {50}, {20}); + assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {50}, {20}, {bucketStartTimeNs}, + {bucket2StartTimeNs}); } TEST(ValueMetricProducerTest, TestAnomalyDetection) { @@ -1012,7 +1083,8 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) { EXPECT_EQ(true, curBaseInfo.hasBase); EXPECT_EQ(23, curBaseInfo.base.long_value); EXPECT_EQ(false, curInterval.hasValue); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs}, + {bucket2StartTimeNs}, {bucket3StartTimeNs}); // pull 3 come late. // The previous bucket gets closed with error. (Has start value 23, no ending) @@ -1028,7 +1100,15 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) { EXPECT_EQ(true, curBaseInfo.hasBase); EXPECT_EQ(36, curBaseInfo.base.long_value); EXPECT_EQ(false, curInterval.hasValue); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs}, + {bucket2StartTimeNs}, {bucket3StartTimeNs}); + // The 3rd bucket is dropped due to multiple buckets being skipped. + ASSERT_EQ(1, valueProducer->mSkippedBuckets.size()); + EXPECT_EQ(bucket3StartTimeNs, valueProducer->mSkippedBuckets[0].bucketStartTimeNs); + EXPECT_EQ(bucket4StartTimeNs, valueProducer->mSkippedBuckets[0].bucketEndTimeNs); + ASSERT_EQ(1, valueProducer->mSkippedBuckets[0].dropEvents.size()); + EXPECT_EQ(MULTIPLE_BUCKETS_SKIPPED, valueProducer->mSkippedBuckets[0].dropEvents[0].reason); + EXPECT_EQ(bucket6StartTimeNs, valueProducer->mSkippedBuckets[0].dropEvents[0].dropTimeNs); } /* @@ -1073,7 +1153,8 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) { valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1); curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); EXPECT_EQ(false, curBaseInfo.hasBase); // Now the alarm is delivered. @@ -1082,7 +1163,8 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) { allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 110)); valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(false, curBaseInfo.hasBase); @@ -1090,10 +1172,9 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) { } /* -* Test pulled event with non sliced condition. The pull on boundary come late, after the -condition -* change to false, and then true again. This is due to alarm delivered late. -*/ + * Test pulled event with non sliced condition. The pull on boundary come late, after the condition + * change to false, and then true again. This is due to alarm delivered late. + */ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) { ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); @@ -1139,7 +1220,8 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) { // pull on bucket boundary come late, condition change happens before it valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; @@ -1148,7 +1230,8 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) { // condition changed to true again, before the pull alarm is delivered valueProducer->onConditionChanged(true, bucket2StartTimeNs + 25); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase); @@ -1167,13 +1250,15 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) { EXPECT_EQ(140, curBaseInfo.base.long_value); EXPECT_EQ(true, curInterval.hasValue); EXPECT_EQ(10, curInterval.value.long_value); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); allData.clear(); allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs, 160)); valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20, 30}, - {bucketSizeNs - 8, bucketSizeNs - 24}); + assertPastBucketValuesSingleKey( + valueProducer->mPastBuckets, {20, 30}, {bucketSizeNs - 8, bucketSizeNs - 24}, + {bucketStartTimeNs, bucket2StartTimeNs}, {bucket2StartTimeNs, bucket3StartTimeNs}); } TEST(ValueMetricProducerTest, TestPushedAggregateMin) { @@ -1216,7 +1301,8 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMin) { EXPECT_EQ(10, curInterval.value.long_value); valueProducer.flushIfNeededLocked(bucket2StartTimeNs); - assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, {bucketSizeNs}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); } TEST(ValueMetricProducerTest, TestPushedAggregateMax) { @@ -1239,9 +1325,6 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMax) { LogEvent event1(/*uid=*/0, /*pid=*/0); CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10); - - LogEvent event2(/*uid=*/0, /*pid=*/0); - CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); // has one slice @@ -1251,6 +1334,8 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMax) { EXPECT_EQ(10, curInterval.value.long_value); EXPECT_EQ(true, curInterval.hasValue); + LogEvent event2(/*uid=*/0, /*pid=*/0); + CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2); // has one slice @@ -1258,10 +1343,9 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMax) { curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; EXPECT_EQ(20, curInterval.value.long_value); - valueProducer.flushIfNeededLocked(bucket3StartTimeNs); - /* EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); */ - /* EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size()); */ - /* EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value); */ + valueProducer.flushIfNeededLocked(bucket2StartTimeNs); + assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {bucketSizeNs}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); } TEST(ValueMetricProducerTest, TestPushedAggregateAvg) { @@ -1351,7 +1435,8 @@ TEST(ValueMetricProducerTest, TestPushedAggregateSum) { EXPECT_EQ(25, curInterval.value.long_value); valueProducer.flushIfNeededLocked(bucket2StartTimeNs); - assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {25}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {25}, {bucketSizeNs}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); } TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) { @@ -1375,10 +1460,8 @@ TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) { LogEvent event1(/*uid=*/0, /*pid=*/0); CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10); - - LogEvent event2(/*uid=*/0, /*pid=*/0); - CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 15); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); + // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); ValueMetricProducer::Interval curInterval = @@ -1388,6 +1471,8 @@ TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) { EXPECT_EQ(10, curBaseInfo.base.long_value); EXPECT_EQ(false, curInterval.hasValue); + LogEvent event2(/*uid=*/0, /*pid=*/0); + CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 15); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2); // has one slice @@ -1400,12 +1485,14 @@ TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) { LogEvent event3(/*uid=*/0, /*pid=*/0); CreateRepeatedValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 15); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3); + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase); EXPECT_EQ(15, curBaseInfo.base.long_value); EXPECT_EQ(true, curInterval.hasValue); + EXPECT_EQ(0, curInterval.value.long_value); LogEvent event4(/*uid=*/0, /*pid=*/0); CreateRepeatedValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 15); @@ -1416,11 +1503,11 @@ TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) { EXPECT_EQ(true, curBaseInfo.hasBase); EXPECT_EQ(15, curBaseInfo.base.long_value); EXPECT_EQ(true, curInterval.hasValue); + EXPECT_EQ(0, curInterval.value.long_value); valueProducer.flushIfNeededLocked(bucket3StartTimeNs); - EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); - EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size()); - assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {5}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {5}, {bucketSizeNs}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); } TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) { @@ -1740,8 +1827,8 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { EXPECT_EQ(3, baseInfo1.base.long_value); EXPECT_EQ(false, interval1.hasValue); EXPECT_EQ(0UL, valueProducer->mPastBuckets.size()); - vector<shared_ptr<LogEvent>> allData; + vector<shared_ptr<LogEvent>> allData; allData.clear(); allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 2, 4)); allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11)); @@ -1753,7 +1840,8 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { EXPECT_EQ(false, interval1.hasValue); EXPECT_EQ(8, interval1.value.long_value); EXPECT_FALSE(interval1.seenNewData); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); auto it = valueProducer->mCurrentSlicedBucket.begin(); for (; it != valueProducer->mCurrentSlicedBucket.end(); it++) { @@ -1769,14 +1857,13 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { } EXPECT_TRUE(it != iter); EXPECT_TRUE(itBase != iterBase); - auto& interval2 = it->second[0]; - auto& baseInfo2 = itBase->second[0]; + auto interval2 = it->second[0]; + auto baseInfo2 = itBase->second[0]; EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value); EXPECT_EQ(true, baseInfo2.hasBase); EXPECT_EQ(4, baseInfo2.base.long_value); EXPECT_EQ(false, interval2.hasValue); EXPECT_FALSE(interval2.seenNewData); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs}); // next pull somehow did not happen, skip to end of bucket 3 allData.clear(); @@ -1791,7 +1878,8 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { EXPECT_EQ(5, baseInfo2.base.long_value); EXPECT_EQ(false, interval2.hasValue); EXPECT_FALSE(interval2.seenNewData); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); allData.clear(); allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 2, 14)); @@ -1805,9 +1893,13 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { EXPECT_FALSE(interval2.seenNewData); ASSERT_EQ(2UL, valueProducer->mPastBuckets.size()); auto iterator = valueProducer->mPastBuckets.begin(); + EXPECT_EQ(bucket4StartTimeNs, iterator->second[0].mBucketStartNs); + EXPECT_EQ(bucket5StartTimeNs, iterator->second[0].mBucketEndNs); EXPECT_EQ(9, iterator->second[0].values[0].long_value); EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs); iterator++; + EXPECT_EQ(bucketStartTimeNs, iterator->second[0].mBucketStartNs); + EXPECT_EQ(bucket2StartTimeNs, iterator->second[0].mBucketEndNs); EXPECT_EQ(8, iterator->second[0].values[0].long_value); EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs); } @@ -2414,7 +2506,8 @@ TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) { EXPECT_EQ(true, valueProducer->mHasGlobalBase); EXPECT_EQ(1UL, valueProducer->mPastBuckets.size()); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); } TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) { @@ -2461,10 +2554,11 @@ TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) { EXPECT_EQ(true, valueProducer->mHasGlobalBase); } -TEST(ValueMetricProducerTest, TestFullBucketResetWhenLastBucketInvalid) { +TEST_P(ValueMetricProducerTest_PartialBucket, TestFullBucketResetWhenLastBucketInvalid) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + int64_t partialBucketSplitTimeNs = bucketStartTimeNs + bucketSizeNs / 2; EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)) // Initialization. .WillOnce(Invoke( @@ -2474,23 +2568,41 @@ TEST(ValueMetricProducerTest, TestFullBucketResetWhenLastBucketInvalid) { return true; })) // notifyAppUpgrade. - .WillOnce(Invoke([](int tagId, const ConfigKey&, - vector<std::shared_ptr<LogEvent>>* data, bool) { + .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&, + vector<std::shared_ptr<LogEvent>>* data, + bool) { data->clear(); - data->push_back(CreateRepeatedValueLogEvent( - tagId, bucketStartTimeNs + bucketSizeNs / 2, 10)); + data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10)); return true; })); sp<ValueMetricProducer> valueProducer = ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size()); - valueProducer->notifyAppUpgrade(bucketStartTimeNs + bucketSizeNs / 2, "com.foo", 10000, 1); + switch (GetParam()) { + case APP_UPGRADE: + valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } + EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs); + EXPECT_EQ(0, valueProducer->getCurrentBucketNum()); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, + {partialBucketSplitTimeNs - bucketStartTimeNs}, + {bucketStartTimeNs}, {partialBucketSplitTimeNs}); ASSERT_EQ(1UL, valueProducer->mCurrentFullBucket.size()); vector<shared_ptr<LogEvent>> allData; allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 4)); valueProducer->onDataPulled(allData, /** fails */ false, bucket3StartTimeNs + 1); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, + {partialBucketSplitTimeNs - bucketStartTimeNs}, + {bucketStartTimeNs}, {partialBucketSplitTimeNs}); + ASSERT_EQ(1, valueProducer->mSkippedBuckets.size()); + EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mSkippedBuckets[0].bucketStartTimeNs); + EXPECT_EQ(bucket2StartTimeNs, valueProducer->mSkippedBuckets[0].bucketEndTimeNs); ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size()); } @@ -2537,7 +2649,8 @@ TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) { valueProducer->onConditionChanged(false, bucket3StartTimeNs + 10); // Bucket should have been completed. - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {bucketSizeNs - 10}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {bucketSizeNs - 10}, + {bucket2StartTimeNs}, {bucket3StartTimeNs}); } TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) { @@ -2557,7 +2670,8 @@ TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) { valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); // Bucket should have been completed. - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); } TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) { @@ -2585,12 +2699,14 @@ TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) { valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); // Bucket should have been completed. - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {19}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {19}, {bucketSizeNs}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); } -TEST(ValueMetricProducerTest, TestBucketBoundariesOnAppUpgrade) { +TEST_P(ValueMetricProducerTest_PartialBucket, TestBucketBoundariesOnPartialBucket) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); + int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2; sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)) // Initialization. @@ -2601,20 +2717,29 @@ TEST(ValueMetricProducerTest, TestBucketBoundariesOnAppUpgrade) { return true; })) // notifyAppUpgrade. - .WillOnce(Invoke([](int tagId, const ConfigKey&, - vector<std::shared_ptr<LogEvent>>* data, bool) { + .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&, + vector<std::shared_ptr<LogEvent>>* data, + bool) { data->clear(); - data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 2, 10)); + data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10)); return true; })); sp<ValueMetricProducer> valueProducer = ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); - valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1); + switch (GetParam()) { + case APP_UPGRADE: + valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs); + break; + case BOOT_COMPLETE: + valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs); + break; + } // Bucket should have been completed. - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, {bucketSizeNs}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); } TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) { @@ -2642,7 +2767,7 @@ TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) { valueProducer->onConditionChanged(true, bucketStartTimeNs + 8); valueProducer->onConditionChanged(false, bucketStartTimeNs + 10); - valueProducer->onConditionChanged(false, bucketStartTimeNs + 10); + valueProducer->onConditionChanged(false, bucketStartTimeNs + 12); EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; @@ -2654,7 +2779,8 @@ TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) { allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 10)); valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {2}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {2}, {bucketStartTimeNs}, + {bucket2StartTimeNs}); } // TODO: b/145705635 fix or delete this test @@ -2705,7 +2831,7 @@ TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) { valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); // There was not global base available so all buckets are invalid. - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {}); } TEST(ValueMetricProducerTest, TestPullNeededFastDump) { @@ -2849,7 +2975,8 @@ TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition) { valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 30); // Bucket should have been completed. - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); } TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges) { @@ -2892,7 +3019,8 @@ TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 110)); valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {50 - 8}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {50 - 8}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(false, curBaseInfo.hasBase); @@ -2923,7 +3051,8 @@ TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) { allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30)); valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs - 8}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs - 8}, + {bucketStartTimeNs}, {bucket2StartTimeNs}); ValueMetricProducer::Interval curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; @@ -2946,7 +3075,7 @@ TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse) { valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); // Condition was always false. - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {}); } TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) { @@ -2976,7 +3105,7 @@ TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) { valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); // No buckets, we had a failure. - assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {}); } /* diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h index 69f7e3f49792..be410b10d43b 100644 --- a/cmds/statsd/tests/metrics/metrics_test_helper.h +++ b/cmds/statsd/tests/metrics/metrics_test_helper.h @@ -44,7 +44,8 @@ public: vector<std::shared_ptr<LogEvent>>* data, bool useUids)); MOCK_METHOD2(RegisterPullUidProvider, void(const ConfigKey& configKey, wp<PullUidProvider> provider)); - MOCK_METHOD1(UnregisterPullUidProvider, void(const ConfigKey& configKey)); + MOCK_METHOD2(UnregisterPullUidProvider, + void(const ConfigKey& configKey, wp<PullUidProvider> provider)); }; class MockUidMap : public UidMap { diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h index 37b98891797a..4d68ea2ecb79 100644 --- a/cmds/statsd/tests/statsd_test_util.h +++ b/cmds/statsd/tests/statsd_test_util.h @@ -42,6 +42,8 @@ using Status = ::ndk::ScopedAStatus; const int SCREEN_STATE_ATOM_ID = util::SCREEN_STATE_CHANGED; const int UID_PROCESS_STATE_ATOM_ID = util::UID_PROCESS_STATE_CHANGED; +enum BucketSplitEvent { APP_UPGRADE, BOOT_COMPLETE }; + // Converts a ProtoOutputStream to a StatsLogReport proto. StatsLogReport outputStreamToProto(ProtoOutputStream* proto); diff --git a/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp b/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp new file mode 100644 index 000000000000..db402a0dd658 --- /dev/null +++ b/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "utils/MultiConditionTrigger.h" + +#include <gtest/gtest.h> + +#include <chrono> +#include <set> +#include <thread> +#include <vector> + +#ifdef __ANDROID__ + +using namespace std; +using std::this_thread::sleep_for; + +namespace android { +namespace os { +namespace statsd { + +TEST(MultiConditionTrigger, TestMultipleConditions) { + int numConditions = 5; + string t1 = "t1", t2 = "t2", t3 = "t3", t4 = "t4", t5 = "t5"; + set<string> conditionNames = {t1, t2, t3, t4, t5}; + + mutex lock; + condition_variable cv; + bool triggerCalled = false; + + // Mark done as true and notify in the done. + MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled] { + { + lock_guard lg(lock); + triggerCalled = true; + } + cv.notify_all(); + }); + + vector<thread> threads; + vector<bool> done(numConditions, false); + + int i = 0; + for (const string& conditionName : conditionNames) { + threads.emplace_back([&done, &conditionName, &trigger, i] { + sleep_for(chrono::milliseconds(3)); + done[i] = true; + trigger.markComplete(conditionName); + }); + i++; + } + + unique_lock<mutex> unique_lk(lock); + cv.wait(unique_lk, [&triggerCalled] { + return triggerCalled; + }); + + for (i = 0; i < numConditions; i++) { + EXPECT_EQ(done[i], 1); + } + + for (i = 0; i < numConditions; i++) { + threads[i].join(); + } +} + +TEST(MultiConditionTrigger, TestNoConditions) { + mutex lock; + condition_variable cv; + bool triggerCalled = false; + + MultiConditionTrigger trigger({}, [&lock, &cv, &triggerCalled] { + { + lock_guard lg(lock); + triggerCalled = true; + } + cv.notify_all(); + }); + + unique_lock<mutex> unique_lk(lock); + cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; }); + EXPECT_TRUE(triggerCalled); + // Ensure that trigger occurs immediately if no events need to be completed. +} + +TEST(MultiConditionTrigger, TestMarkCompleteCalledBySameCondition) { + string t1 = "t1", t2 = "t2"; + set<string> conditionNames = {t1, t2}; + + mutex lock; + condition_variable cv; + bool triggerCalled = false; + + MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled] { + { + lock_guard lg(lock); + triggerCalled = true; + } + cv.notify_all(); + }); + + trigger.markComplete(t1); + trigger.markComplete(t1); + + // Ensure that the trigger still hasn't fired. + { + lock_guard lg(lock); + EXPECT_FALSE(triggerCalled); + } + + trigger.markComplete(t2); + unique_lock<mutex> unique_lk(lock); + cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; }); + EXPECT_TRUE(triggerCalled); +} + +TEST(MultiConditionTrigger, TestTriggerOnlyCalledOnce) { + string t1 = "t1"; + set<string> conditionNames = {t1}; + + mutex lock; + condition_variable cv; + bool triggerCalled = false; + int triggerCount = 0; + + MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled, &triggerCount] { + { + lock_guard lg(lock); + triggerCount++; + triggerCalled = true; + } + cv.notify_all(); + }); + + trigger.markComplete(t1); + + // Ensure that the trigger fired. + { + unique_lock<mutex> unique_lk(lock); + cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; }); + EXPECT_TRUE(triggerCalled); + EXPECT_EQ(triggerCount, 1); + triggerCalled = false; + } + + trigger.markComplete(t1); + + // Ensure that the trigger does not fire again. + { + unique_lock<mutex> unique_lk(lock); + cv.wait_for(unique_lk, chrono::milliseconds(5), [&triggerCalled] { return triggerCalled; }); + EXPECT_FALSE(triggerCalled); + EXPECT_EQ(triggerCount, 1); + } +} + +} // namespace statsd +} // namespace os +} // namespace android +#else +GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif diff --git a/cmds/statsd/tests/utils/NamedLatch_test.cpp b/cmds/statsd/tests/utils/NamedLatch_test.cpp deleted file mode 100644 index de48a133823e..000000000000 --- a/cmds/statsd/tests/utils/NamedLatch_test.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "utils/NamedLatch.h" - -#include <gtest/gtest.h> - -#include <chrono> -#include <set> -#include <thread> -#include <vector> - -#ifdef __ANDROID__ - -using namespace std; -using std::this_thread::sleep_for; - -namespace android { -namespace os { -namespace statsd { - -TEST(NamedLatchTest, TestWait) { - int numEvents = 5; - string t1 = "t1", t2 = "t2", t3 = "t3", t4 = "t4", t5 = "t5"; - set<string> eventNames = {t1, t2, t3, t4, t5}; - - NamedLatch latch(eventNames); - vector<thread> threads; - vector<bool> done(numEvents, false); - - int i = 0; - for (const string& eventName : eventNames) { - threads.emplace_back([&done, &eventName, &latch, i] { - sleep_for(chrono::milliseconds(3)); - done[i] = true; - latch.countDown(eventName); - }); - i++; - } - - latch.wait(); - - for (i = 0; i < numEvents; i++) { - EXPECT_EQ(done[i], 1); - } - - for (i = 0; i < numEvents; i++) { - threads[i].join(); - } -} - -TEST(NamedLatchTest, TestNoWorkers) { - NamedLatch latch({}); - latch.wait(); - // Ensure that latch does not wait if no events need to countDown. -} - -TEST(NamedLatchTest, TestCountDownCalledBySameEventName) { - string t1 = "t1", t2 = "t2"; - set<string> eventNames = {t1, t2}; - - NamedLatch latch(eventNames); - - thread waiterThread([&latch] { latch.wait(); }); - - latch.countDown(t1); - latch.countDown(t1); - - // Ensure that the latch's remaining threads still has t2. - latch.mMutex.lock(); - ASSERT_EQ(latch.mRemainingEventNames.size(), 1); - EXPECT_NE(latch.mRemainingEventNames.find(t2), latch.mRemainingEventNames.end()); - latch.mMutex.unlock(); - - latch.countDown(t2); - waiterThread.join(); -} - -} // namespace statsd -} // namespace os -} // namespace android -#else -GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif diff --git a/cmds/uiautomator/library/Android.bp b/cmds/uiautomator/library/Android.bp index 3a260639de0f..c33d31f576a3 100644 --- a/cmds/uiautomator/library/Android.bp +++ b/cmds/uiautomator/library/Android.bp @@ -28,9 +28,6 @@ droiddoc { installable: false, args: "-stubpackages com.android.uiautomator.core:" + "com.android.uiautomator.testrunner", - api_tag_name: "UIAUTOMATOR", - api_filename: "uiautomator_api.txt", - removed_api_filename: "uiautomator_removed_api.txt", check_api: { current: { diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 21b56d3e337f..7d6ce41763d7 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -375,7 +375,6 @@ public final class ActivityThread extends ClientTransactionHandler { String mInstrumentedLibDir = null; boolean mSystemThread = false; boolean mSomeActivitiesChanged = false; - boolean mUpdatingSystemConfig = false; /* package */ boolean mHiddenApiWarningShown = false; // These can be accessed by multiple threads; mResourcesManager is the lock. @@ -587,8 +586,11 @@ public final class ActivityThread extends ClientTransactionHandler { throw new IllegalStateException( "Received config update for non-existing activity"); } + // Given alwaysReportChange=false because the configuration is from view root, the + // activity may not be able to handle the changes. In that case the activity will be + // relaunched immediately, then Activity#onConfigurationChanged shouldn't be called. activity.mMainThread.handleActivityConfigurationChanged(token, overrideConfig, - newDisplayId); + newDisplayId, false /* alwaysReportChange */); }; } @@ -2029,12 +2031,7 @@ public final class ActivityThread extends ClientTransactionHandler { break; } case APPLICATION_INFO_CHANGED: - mUpdatingSystemConfig = true; - try { - handleApplicationInfoChanged((ApplicationInfo) msg.obj); - } finally { - mUpdatingSystemConfig = false; - } + handleApplicationInfoChanged((ApplicationInfo) msg.obj); break; case RUN_ISOLATED_ENTRY_POINT: handleRunIsolatedEntryPoint((String) ((SomeArgs) msg.obj).arg1, @@ -2238,7 +2235,9 @@ public final class ActivityThread extends ClientTransactionHandler { LoadedApk packageInfo = ref != null ? ref.get() : null; if (ai != null && packageInfo != null) { if (!isLoadedApkResourceDirsUpToDate(packageInfo, ai)) { - packageInfo.updateApplicationInfo(ai, null); + List<String> oldPaths = new ArrayList<>(); + LoadedApk.makePaths(this, ai, oldPaths); + packageInfo.updateApplicationInfo(ai, oldPaths); } if (packageInfo.isSecurityViolation() @@ -2326,7 +2325,9 @@ public final class ActivityThread extends ClientTransactionHandler { if (packageInfo != null) { if (!isLoadedApkResourceDirsUpToDate(packageInfo, aInfo)) { - packageInfo.updateApplicationInfo(aInfo, null); + List<String> oldPaths = new ArrayList<>(); + LoadedApk.makePaths(this, aInfo, oldPaths); + packageInfo.updateApplicationInfo(aInfo, oldPaths); } return packageInfo; @@ -4467,7 +4468,8 @@ public final class ActivityThread extends ClientTransactionHandler { // simply finishing, and we are not starting another activity. if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) { if (r.newConfig != null) { - performConfigurationChangedForActivity(r, r.newConfig); + performConfigurationChangedForActivity(r, r.newConfig, + false /* alwaysReportChange */); if (DEBUG_CONFIGURATION) { Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig); @@ -4787,7 +4789,8 @@ public final class ActivityThread extends ClientTransactionHandler { } } if (r.newConfig != null) { - performConfigurationChangedForActivity(r, r.newConfig); + performConfigurationChangedForActivity(r, r.newConfig, + false /* alwaysReportChange */); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " + r.activityInfo.name + " with new config " + r.activity.mCurrentConfig); @@ -5447,11 +5450,12 @@ public final class ActivityThread extends ClientTransactionHandler { * @param r ActivityClientRecord representing the Activity. * @param newBaseConfig The new configuration to use. This may be augmented with * {@link ActivityClientRecord#overrideConfig}. + * @param alwaysReportChange If the configuration is changed, always report to activity. */ private void performConfigurationChangedForActivity(ActivityClientRecord r, - Configuration newBaseConfig) { - performConfigurationChangedForActivity(r, newBaseConfig, - r.activity.getDisplayId(), false /* movedToDifferentDisplay */); + Configuration newBaseConfig, boolean alwaysReportChange) { + performConfigurationChangedForActivity(r, newBaseConfig, r.activity.getDisplayId(), + false /* movedToDifferentDisplay */, alwaysReportChange); } /** @@ -5464,16 +5468,19 @@ public final class ActivityThread extends ClientTransactionHandler { * {@link ActivityClientRecord#overrideConfig}. * @param displayId The id of the display where the Activity currently resides. * @param movedToDifferentDisplay Indicates if the activity was moved to different display. + * @param alwaysReportChange If the configuration is changed, always report to activity. * @return {@link Configuration} instance sent to client, null if not sent. */ private Configuration performConfigurationChangedForActivity(ActivityClientRecord r, - Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay) { + Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay, + boolean alwaysReportChange) { r.tmpConfig.setTo(newBaseConfig); if (r.overrideConfig != null) { r.tmpConfig.updateFrom(r.overrideConfig); } final Configuration reportedConfig = performActivityConfigurationChanged(r.activity, - r.tmpConfig, r.overrideConfig, displayId, movedToDifferentDisplay); + r.tmpConfig, r.overrideConfig, displayId, movedToDifferentDisplay, + alwaysReportChange); freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); return reportedConfig; } @@ -5529,11 +5536,12 @@ public final class ActivityThread extends ClientTransactionHandler { * ActivityManager. * @param displayId Id of the display where activity currently resides. * @param movedToDifferentDisplay Indicates if the activity was moved to different display. + * @param alwaysReportChange If the configuration is changed, always report to activity. * @return Configuration sent to client, null if no changes and not moved to different display. */ private Configuration performActivityConfigurationChanged(Activity activity, Configuration newConfig, Configuration amOverrideConfig, int displayId, - boolean movedToDifferentDisplay) { + boolean movedToDifferentDisplay, boolean alwaysReportChange) { if (activity == null) { throw new IllegalArgumentException("No activity provided."); } @@ -5556,7 +5564,7 @@ public final class ActivityThread extends ClientTransactionHandler { // Always send the task-level config changes. For system-level configuration, if // this activity doesn't handle any of the config changes, then don't bother // calling onConfigurationChanged as we're going to destroy it. - if (!mUpdatingSystemConfig + if (alwaysReportChange || (~activity.mActivityInfo.getRealConfigChanged() & diff) == 0 || !REPORT_TO_ACTIVITY) { shouldChangeConfig = true; @@ -5638,12 +5646,7 @@ public final class ActivityThread extends ClientTransactionHandler { public void handleConfigurationChanged(Configuration config) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged"); mCurDefaultDisplayDpi = config.densityDpi; - mUpdatingSystemConfig = true; - try { - handleConfigurationChanged(config, null /* compat */); - } finally { - mUpdatingSystemConfig = false; - } + handleConfigurationChanged(config, null /* compat */); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } @@ -5725,7 +5728,7 @@ public final class ActivityThread extends ClientTransactionHandler { // config and avoid onConfigurationChanged if it hasn't changed. Activity a = (Activity) cb; performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()), - config); + config, false /* alwaysReportChange */); } else if (!equivalent) { performConfigurationChanged(cb, config); } else { @@ -5832,16 +5835,28 @@ public final class ActivityThread extends ClientTransactionHandler { } } + @Override + public void handleActivityConfigurationChanged(IBinder activityToken, + Configuration overrideConfig, int displayId) { + handleActivityConfigurationChanged(activityToken, overrideConfig, displayId, + // This is the only place that uses alwaysReportChange=true. The entry point should + // be from ActivityConfigurationChangeItem or MoveToDisplayItem, so the server side + // has confirmed the activity should handle the configuration instead of relaunch. + // If Activity#onConfigurationChanged is called unexpectedly, then we can know it is + // something wrong from server side. + true /* alwaysReportChange */); + } + /** * Handle new activity configuration and/or move to a different display. * @param activityToken Target activity token. * @param overrideConfig Activity override config. * @param displayId Id of the display where activity was moved to, -1 if there was no move and * value didn't change. + * @param alwaysReportChange If the configuration is changed, always report to activity. */ - @Override - public void handleActivityConfigurationChanged(IBinder activityToken, - Configuration overrideConfig, int displayId) { + void handleActivityConfigurationChanged(IBinder activityToken, Configuration overrideConfig, + int displayId, boolean alwaysReportChange) { ActivityClientRecord r = mActivities.get(activityToken); // Check input params. if (r == null || r.activity == null) { @@ -5880,14 +5895,15 @@ public final class ActivityThread extends ClientTransactionHandler { + ", config=" + overrideConfig); final Configuration reportedConfig = performConfigurationChangedForActivity(r, - mCompatConfiguration, displayId, true /* movedToDifferentDisplay */); + mCompatConfiguration, displayId, true /* movedToDifferentDisplay */, + alwaysReportChange); if (viewRoot != null) { viewRoot.onMovedToDisplay(displayId, reportedConfig); } } else { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " + r.activityInfo.name + ", config=" + overrideConfig); - performConfigurationChangedForActivity(r, mCompatConfiguration); + performConfigurationChangedForActivity(r, mCompatConfiguration, alwaysReportChange); } // Notify the ViewRootImpl instance about configuration changes. It may have initiated this // update to make sure that resources are updated before updating itself. diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 9d0364eba39f..8dfce14af5f7 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -58,6 +58,7 @@ interface INotificationManager void setShowBadge(String pkg, int uid, boolean showBadge); boolean canShowBadge(String pkg, int uid); + boolean hasSentMessage(String pkg, int uid); void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled); /** * Updates the notification's enabled state. Additionally locks importance for all of the diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 8edf03d033f8..af027837ec91 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -2301,11 +2301,11 @@ public class Notification implements Parcelable priority = parcel.readInt(); - category = parcel.readString(); + category = parcel.readString8(); - mGroupKey = parcel.readString(); + mGroupKey = parcel.readString8(); - mSortKey = parcel.readString(); + mSortKey = parcel.readString8(); extras = Bundle.setDefusable(parcel.readBundle(), true); // may be null fixDuplicateExtras(); @@ -2329,12 +2329,12 @@ public class Notification implements Parcelable color = parcel.readInt(); if (parcel.readInt() != 0) { - mChannelId = parcel.readString(); + mChannelId = parcel.readString8(); } mTimeout = parcel.readLong(); if (parcel.readInt() != 0) { - mShortcutId = parcel.readString(); + mShortcutId = parcel.readString8(); } if (parcel.readInt() != 0) { @@ -2766,11 +2766,11 @@ public class Notification implements Parcelable parcel.writeInt(priority); - parcel.writeString(category); + parcel.writeString8(category); - parcel.writeString(mGroupKey); + parcel.writeString8(mGroupKey); - parcel.writeString(mSortKey); + parcel.writeString8(mSortKey); parcel.writeBundle(extras); // null ok @@ -2803,7 +2803,7 @@ public class Notification implements Parcelable if (mChannelId != null) { parcel.writeInt(1); - parcel.writeString(mChannelId); + parcel.writeString8(mChannelId); } else { parcel.writeInt(0); } @@ -2811,7 +2811,7 @@ public class Notification implements Parcelable if (mShortcutId != null) { parcel.writeInt(1); - parcel.writeString(mShortcutId); + parcel.writeString8(mShortcutId); } else { parcel.writeInt(0); } @@ -8873,7 +8873,7 @@ public class Notification implements Parcelable } mDesiredHeightResId = in.readInt(); if (in.readInt() != 0) { - mShortcutId = in.readString(); + mShortcutId = in.readString8(); } } @@ -9029,7 +9029,7 @@ public class Notification implements Parcelable out.writeInt(mDesiredHeightResId); out.writeInt(TextUtils.isEmpty(mShortcutId) ? 0 : 1); if (!TextUtils.isEmpty(mShortcutId)) { - out.writeString(mShortcutId); + out.writeString8(mShortcutId); } } diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java index 2feb9277775c..9f8d3c4090d6 100644 --- a/core/java/android/app/NotificationChannel.java +++ b/core/java/android/app/NotificationChannel.java @@ -102,7 +102,7 @@ public final class NotificationChannel implements Parcelable { private static final String ATT_FG_SERVICE_SHOWN = "fgservice"; private static final String ATT_GROUP = "group"; private static final String ATT_BLOCKABLE_SYSTEM = "blockable_system"; - private static final String ATT_ALLOW_BUBBLE = "allow_bubble"; + private static final String ATT_ALLOW_BUBBLE = "allow_bubbles"; private static final String ATT_ORIG_IMP = "orig_imp"; private static final String ATT_PARENT_CHANNEL = "parent"; private static final String ATT_CONVERSATION_ID = "conv_id"; @@ -168,7 +168,12 @@ public final class NotificationChannel implements Parcelable { NotificationManager.IMPORTANCE_UNSPECIFIED; private static final boolean DEFAULT_DELETED = false; private static final boolean DEFAULT_SHOW_BADGE = true; - private static final boolean DEFAULT_ALLOW_BUBBLE = false; + /** + * @hide + */ + public static final int DEFAULT_ALLOW_BUBBLE = -1; + private static final int ALLOW_BUBBLE_ON = 1; + private static final int ALLOW_BUBBLE_OFF = 0; @UnsupportedAppUsage private String mId; @@ -193,7 +198,7 @@ public final class NotificationChannel implements Parcelable { private AudioAttributes mAudioAttributes = Notification.AUDIO_ATTRIBUTES_DEFAULT; // If this is a blockable system notification channel. private boolean mBlockableSystem = false; - private boolean mAllowBubbles = DEFAULT_ALLOW_BUBBLE; + private int mAllowBubbles = DEFAULT_ALLOW_BUBBLE; private boolean mImportanceLockedByOEM; private boolean mImportanceLockedDefaultApp; private String mParentId = null; @@ -261,7 +266,7 @@ public final class NotificationChannel implements Parcelable { mAudioAttributes = in.readInt() > 0 ? AudioAttributes.CREATOR.createFromParcel(in) : null; mLightColor = in.readInt(); mBlockableSystem = in.readBoolean(); - mAllowBubbles = in.readBoolean(); + mAllowBubbles = in.readInt(); mImportanceLockedByOEM = in.readBoolean(); mOriginalImportance = in.readInt(); mParentId = in.readString(); @@ -320,7 +325,7 @@ public final class NotificationChannel implements Parcelable { } dest.writeInt(mLightColor); dest.writeBoolean(mBlockableSystem); - dest.writeBoolean(mAllowBubbles); + dest.writeInt(mAllowBubbles); dest.writeBoolean(mImportanceLockedByOEM); dest.writeInt(mOriginalImportance); dest.writeString(mParentId); @@ -550,7 +555,14 @@ public final class NotificationChannel implements Parcelable { * @see Notification#getBubbleMetadata() */ public void setAllowBubbles(boolean allowBubbles) { - mAllowBubbles = allowBubbles; + mAllowBubbles = allowBubbles ? ALLOW_BUBBLE_ON : ALLOW_BUBBLE_OFF; + } + + /** + * @hide + */ + public void setAllowBubbles(int allowed) { + mAllowBubbles = allowed; } /** @@ -701,6 +713,13 @@ public final class NotificationChannel implements Parcelable { * @see Notification#getBubbleMetadata() */ public boolean canBubble() { + return mAllowBubbles == ALLOW_BUBBLE_ON; + } + + /** + * @hide + */ + public int getAllowBubbles() { return mAllowBubbles; } @@ -872,7 +891,7 @@ public final class NotificationChannel implements Parcelable { lockFields(safeInt(parser, ATT_USER_LOCKED, 0)); setFgServiceShown(safeBool(parser, ATT_FG_SERVICE_SHOWN, false)); setBlockable(safeBool(parser, ATT_BLOCKABLE_SYSTEM, false)); - setAllowBubbles(safeBool(parser, ATT_ALLOW_BUBBLE, DEFAULT_ALLOW_BUBBLE)); + setAllowBubbles(safeInt(parser, ATT_ALLOW_BUBBLE, DEFAULT_ALLOW_BUBBLE)); setOriginalImportance(safeInt(parser, ATT_ORIG_IMP, DEFAULT_IMPORTANCE)); setConversationId(parser.getAttributeValue(null, ATT_PARENT_CHANNEL), parser.getAttributeValue(null, ATT_CONVERSATION_ID)); @@ -996,8 +1015,8 @@ public final class NotificationChannel implements Parcelable { if (isBlockable()) { out.attribute(null, ATT_BLOCKABLE_SYSTEM, Boolean.toString(isBlockable())); } - if (canBubble() != DEFAULT_ALLOW_BUBBLE) { - out.attribute(null, ATT_ALLOW_BUBBLE, Boolean.toString(canBubble())); + if (getAllowBubbles() != DEFAULT_ALLOW_BUBBLE) { + out.attribute(null, ATT_ALLOW_BUBBLE, Integer.toString(getAllowBubbles())); } if (getOriginalImportance() != DEFAULT_IMPORTANCE) { out.attribute(null, ATT_ORIG_IMP, Integer.toString(getOriginalImportance())); @@ -1059,7 +1078,7 @@ public final class NotificationChannel implements Parcelable { record.put(ATT_DELETED, Boolean.toString(isDeleted())); record.put(ATT_GROUP, getGroup()); record.put(ATT_BLOCKABLE_SYSTEM, isBlockable()); - record.put(ATT_ALLOW_BUBBLE, canBubble()); + record.put(ATT_ALLOW_BUBBLE, getAllowBubbles()); // TODO: original importance return record; } diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java index 0173731995dd..c7a2a1e11c9e 100644 --- a/core/java/android/app/TaskInfo.java +++ b/core/java/android/app/TaskInfo.java @@ -20,6 +20,7 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Intent; @@ -196,6 +197,20 @@ public class TaskInfo { return resizeMode != RESIZE_MODE_UNRESIZEABLE; } + /** @hide */ + @NonNull + @TestApi + public WindowContainerToken getToken() { + return token; + } + + /** @hide */ + @NonNull + @TestApi + public Configuration getConfiguration() { + return configuration; + } + /** * Reads the TaskInfo from a parcel. */ diff --git a/core/java/android/app/WindowContext.java b/core/java/android/app/WindowContext.java index 3a06c9d79fee..cb416c923c60 100644 --- a/core/java/android/app/WindowContext.java +++ b/core/java/android/app/WindowContext.java @@ -16,6 +16,7 @@ package android.app; import static android.view.WindowManagerGlobal.ADD_OKAY; +import static android.view.WindowManagerGlobal.ADD_TOO_MANY_TOKENS; import android.annotation.NonNull; import android.annotation.Nullable; @@ -81,6 +82,11 @@ public class WindowContext extends ContextWrapper { mOwnsToken = false; throw e.rethrowFromSystemServer(); } + if (result == ADD_TOO_MANY_TOKENS) { + throw new UnsupportedOperationException("createWindowContext failed! Too many unused " + + "window contexts. Please see Context#createWindowContext documentation for " + + "detail."); + } mOwnsToken = result == ADD_OKAY; Reference.reachabilityFence(this); } diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java index 9c806fa286bc..1923bf3c5a23 100644 --- a/core/java/android/content/ClipData.java +++ b/core/java/android/content/ClipData.java @@ -1206,7 +1206,7 @@ public class ClipData implements Parcelable { } } else { dest.writeInt(PARCEL_TYPE_STRING); - dest.writeString(text); + dest.writeString8(text); } } @@ -1215,7 +1215,7 @@ public class ClipData implements Parcelable { */ private static String readHtmlTextFromParcel(Parcel in) { if (in.readInt() == PARCEL_TYPE_STRING) { - return in.readString(); + return in.readString8(); } ParcelFileDescriptor pfd = in.readParcelable(ParcelFileDescriptor.class.getClassLoader()); diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java index 494d2aeaf42a..1fb426eb3cfc 100644 --- a/core/java/android/content/ContentProviderOperation.java +++ b/core/java/android/content/ContentProviderOperation.java @@ -91,8 +91,8 @@ public class ContentProviderOperation implements Parcelable { private ContentProviderOperation(Parcel source) { mType = source.readInt(); mUri = Uri.CREATOR.createFromParcel(source); - mMethod = source.readInt() != 0 ? source.readString() : null; - mArg = source.readInt() != 0 ? source.readString() : null; + mMethod = source.readInt() != 0 ? source.readString8() : null; + mArg = source.readInt() != 0 ? source.readString8() : null; final int valuesSize = source.readInt(); if (valuesSize != -1) { mValues = new ArrayMap<>(valuesSize); @@ -107,7 +107,7 @@ public class ContentProviderOperation implements Parcelable { } else { mExtras = null; } - mSelection = source.readInt() != 0 ? source.readString() : null; + mSelection = source.readInt() != 0 ? source.readString8() : null; mSelectionArgs = source.readSparseArray(null); mExpectedCount = source.readInt() != 0 ? source.readInt() : null; mYieldAllowed = source.readInt() != 0; @@ -135,13 +135,13 @@ public class ContentProviderOperation implements Parcelable { Uri.writeToParcel(dest, mUri); if (mMethod != null) { dest.writeInt(1); - dest.writeString(mMethod); + dest.writeString8(mMethod); } else { dest.writeInt(0); } if (mArg != null) { dest.writeInt(1); - dest.writeString(mArg); + dest.writeString8(mArg); } else { dest.writeInt(0); } @@ -159,7 +159,7 @@ public class ContentProviderOperation implements Parcelable { } if (mSelection != null) { dest.writeInt(1); - dest.writeString(mSelection); + dest.writeString8(mSelection); } else { dest.writeInt(0); } @@ -591,7 +591,7 @@ public class ContentProviderOperation implements Parcelable { public BackReference(Parcel src) { this.fromIndex = src.readInt(); if (src.readInt() != 0) { - this.fromKey = src.readString(); + this.fromKey = src.readString8(); } else { this.fromKey = null; } @@ -620,7 +620,7 @@ public class ContentProviderOperation implements Parcelable { dest.writeInt(fromIndex); if (fromKey != null) { dest.writeInt(1); - dest.writeString(fromKey); + dest.writeString8(fromKey); } else { dest.writeInt(0); } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 7c1b62fc9b8e..09c684971549 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -5812,6 +5812,12 @@ public abstract class Context { * display.</b> If there is a need to add different window types, or non-associated windows, * separate Contexts should be used. * </p> + * <p> + * Creating a window context is an expensive operation. Misuse of this API may lead to a huge + * performance drop. The best practice is to use the same window context when possible. + * An approach is to create one window context with specific window type and display and + * use it everywhere it's needed.. + * </p> * * @param type Window type in {@link WindowManager.LayoutParams} * @param options Bundle used to pass window-related options. @@ -5824,7 +5830,9 @@ public abstract class Context { * @see #WINDOW_SERVICE * @see #LAYOUT_INFLATER_SERVICE * @see #WALLPAPER_SERVICE - * @throws IllegalArgumentException if token is invalid + * @throws UnsupportedOperationException if this {@link Context} does not attach to a display or + * the current number of window contexts without adding any view by + * {@link WindowManager#addView} <b>exceeds five</b>. */ public @NonNull Context createWindowContext(@WindowType int type, @Nullable Bundle options) { throw new RuntimeException("Not implemented. Must override in a subclass."); diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index b1d6c830d3b7..def150ab49e5 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -888,8 +888,8 @@ public class Intent implements Parcelable, Cloneable { public ShortcutIconResource createFromParcel(Parcel source) { ShortcutIconResource icon = new ShortcutIconResource(); - icon.packageName = source.readString(); - icon.resourceName = source.readString(); + icon.packageName = source.readString8(); + icon.resourceName = source.readString8(); return icon; } @@ -906,8 +906,8 @@ public class Intent implements Parcelable, Cloneable { } public void writeToParcel(Parcel dest, int flags) { - dest.writeString(packageName); - dest.writeString(resourceName); + dest.writeString8(packageName); + dest.writeString8(resourceName); } @Override @@ -10807,12 +10807,12 @@ public class Intent implements Parcelable, Cloneable { } public void writeToParcel(Parcel out, int flags) { - out.writeString(mAction); + out.writeString8(mAction); Uri.writeToParcel(out, mData); - out.writeString(mType); - out.writeString(mIdentifier); + out.writeString8(mType); + out.writeString8(mIdentifier); out.writeInt(mFlags); - out.writeString(mPackage); + out.writeString8(mPackage); ComponentName.writeToParcel(mComponent, out); if (mSourceBounds != null) { @@ -10826,7 +10826,7 @@ public class Intent implements Parcelable, Cloneable { final int N = mCategories.size(); out.writeInt(N); for (int i=0; i<N; i++) { - out.writeString(mCategories.valueAt(i)); + out.writeString8(mCategories.valueAt(i)); } } else { out.writeInt(0); @@ -10865,12 +10865,12 @@ public class Intent implements Parcelable, Cloneable { } public void readFromParcel(Parcel in) { - setAction(in.readString()); + setAction(in.readString8()); mData = Uri.CREATOR.createFromParcel(in); - mType = in.readString(); - mIdentifier = in.readString(); + mType = in.readString8(); + mIdentifier = in.readString8(); mFlags = in.readInt(); - mPackage = in.readString(); + mPackage = in.readString8(); mComponent = ComponentName.readFromParcel(in); if (in.readInt() != 0) { @@ -10882,7 +10882,7 @@ public class Intent implements Parcelable, Cloneable { mCategories = new ArraySet<String>(); int i; for (i=0; i<N; i++) { - mCategories.add(in.readString().intern()); + mCategories.add(in.readString8().intern()); } } else { mCategories = null; diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index f25ce76d9365..b1f88693d9c0 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -1206,17 +1206,17 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { dest.writeInt(theme); dest.writeInt(launchMode); dest.writeInt(documentLaunchMode); - dest.writeString(permission); - dest.writeString(taskAffinity); - dest.writeString(targetActivity); - dest.writeString(launchToken); + dest.writeString8(permission); + dest.writeString8(taskAffinity); + dest.writeString8(targetActivity); + dest.writeString8(launchToken); dest.writeInt(flags); dest.writeInt(privateFlags); dest.writeInt(screenOrientation); dest.writeInt(configChanges); dest.writeInt(softInputMode); dest.writeInt(uiOptions); - dest.writeString(parentActivityName); + dest.writeString8(parentActivityName); dest.writeInt(persistableMode); dest.writeInt(maxRecents); dest.writeInt(lockTaskLaunchMode); @@ -1227,7 +1227,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { dest.writeInt(0); } dest.writeInt(resizeMode); - dest.writeString(requestedVrComponent); + dest.writeString8(requestedVrComponent); dest.writeInt(rotationAnimation); dest.writeInt(colorMode); dest.writeFloat(maxAspectRatio); @@ -1327,17 +1327,17 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { theme = source.readInt(); launchMode = source.readInt(); documentLaunchMode = source.readInt(); - permission = source.readString(); - taskAffinity = source.readString(); - targetActivity = source.readString(); - launchToken = source.readString(); + permission = source.readString8(); + taskAffinity = source.readString8(); + targetActivity = source.readString8(); + launchToken = source.readString8(); flags = source.readInt(); privateFlags = source.readInt(); screenOrientation = source.readInt(); configChanges = source.readInt(); softInputMode = source.readInt(); uiOptions = source.readInt(); - parentActivityName = source.readString(); + parentActivityName = source.readString8(); persistableMode = source.readInt(); maxRecents = source.readInt(); lockTaskLaunchMode = source.readInt(); @@ -1345,7 +1345,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { windowLayout = new WindowLayout(source); } resizeMode = source.readInt(); - requestedVrComponent = source.readString(); + requestedVrComponent = source.readString8(); rotationAnimation = source.readInt(); colorMode = source.readInt(); maxAspectRatio = source.readFloat(); @@ -1386,7 +1386,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { gravity = source.readInt(); minWidth = source.readInt(); minHeight = source.readInt(); - windowLayoutAffinity = source.readString(); + windowLayoutAffinity = source.readString8(); } /** @@ -1476,7 +1476,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { dest.writeInt(gravity); dest.writeInt(minWidth); dest.writeInt(minHeight); - dest.writeString(windowLayoutAffinity); + dest.writeString8(windowLayoutAffinity); } } } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index b67060111785..b37521b1189b 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -1704,10 +1704,10 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return; } super.writeToParcel(dest, parcelableFlags); - dest.writeString(taskAffinity); - dest.writeString(permission); - dest.writeString(processName); - dest.writeString(className); + dest.writeString8(taskAffinity); + dest.writeString8(permission); + dest.writeString8(processName); + dest.writeString8(className); dest.writeInt(theme); dest.writeInt(flags); dest.writeInt(privateFlags); @@ -1721,28 +1721,28 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } else { dest.writeInt(0); } - dest.writeString(scanSourceDir); - dest.writeString(scanPublicSourceDir); - dest.writeString(sourceDir); - dest.writeString(publicSourceDir); + dest.writeString8(scanSourceDir); + dest.writeString8(scanPublicSourceDir); + dest.writeString8(sourceDir); + dest.writeString8(publicSourceDir); dest.writeStringArray(splitNames); dest.writeStringArray(splitSourceDirs); dest.writeStringArray(splitPublicSourceDirs); dest.writeSparseArray((SparseArray) splitDependencies); - dest.writeString(nativeLibraryDir); - dest.writeString(secondaryNativeLibraryDir); - dest.writeString(nativeLibraryRootDir); + dest.writeString8(nativeLibraryDir); + dest.writeString8(secondaryNativeLibraryDir); + dest.writeString8(nativeLibraryRootDir); dest.writeInt(nativeLibraryRootRequiresIsa ? 1 : 0); - dest.writeString(primaryCpuAbi); - dest.writeString(secondaryCpuAbi); + dest.writeString8(primaryCpuAbi); + dest.writeString8(secondaryCpuAbi); dest.writeStringArray(resourceDirs); - dest.writeString(seInfo); - dest.writeString(seInfoUser); + dest.writeString8(seInfo); + dest.writeString8(seInfoUser); dest.writeStringArray(sharedLibraryFiles); dest.writeTypedList(sharedLibraryInfos); - dest.writeString(dataDir); - dest.writeString(deviceProtectedDataDir); - dest.writeString(credentialProtectedDataDir); + dest.writeString8(dataDir); + dest.writeString8(deviceProtectedDataDir); + dest.writeString8(credentialProtectedDataDir); dest.writeInt(uid); dest.writeInt(minSdkVersion); dest.writeInt(targetSdkVersion); @@ -1750,8 +1750,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeInt(enabled ? 1 : 0); dest.writeInt(enabledSetting); dest.writeInt(installLocation); - dest.writeString(manageSpaceActivityName); - dest.writeString(backupAgentName); + dest.writeString8(manageSpaceActivityName); + dest.writeString8(backupAgentName); dest.writeInt(descriptionRes); dest.writeInt(uiOptions); dest.writeInt(fullBackupContent); @@ -1759,16 +1759,16 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeInt(networkSecurityConfigRes); dest.writeInt(category); dest.writeInt(targetSandboxVersion); - dest.writeString(classLoaderName); + dest.writeString8(classLoaderName); dest.writeStringArray(splitClassLoaderNames); dest.writeInt(compileSdkVersion); - dest.writeString(compileSdkVersionCodename); - dest.writeString(appComponentFactory); + dest.writeString8(compileSdkVersionCodename); + dest.writeString8(appComponentFactory); dest.writeInt(iconRes); dest.writeInt(roundIconRes); dest.writeInt(mHiddenApiPolicy); dest.writeInt(hiddenUntilInstalled ? 1 : 0); - dest.writeString(zygotePreloadName); + dest.writeString8(zygotePreloadName); dest.writeInt(gwpAsanMode); } @@ -1788,10 +1788,10 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { @SuppressWarnings("unchecked") private ApplicationInfo(Parcel source) { super(source); - taskAffinity = source.readString(); - permission = source.readString(); - processName = source.readString(); - className = source.readString(); + taskAffinity = source.readString8(); + permission = source.readString8(); + processName = source.readString8(); + className = source.readString8(); theme = source.readInt(); flags = source.readInt(); privateFlags = source.readInt(); @@ -1802,28 +1802,28 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { storageUuid = new UUID(source.readLong(), source.readLong()); volumeUuid = StorageManager.convert(storageUuid); } - scanSourceDir = source.readString(); - scanPublicSourceDir = source.readString(); - sourceDir = source.readString(); - publicSourceDir = source.readString(); + scanSourceDir = source.readString8(); + scanPublicSourceDir = source.readString8(); + sourceDir = source.readString8(); + publicSourceDir = source.readString8(); splitNames = source.readStringArray(); splitSourceDirs = source.readStringArray(); splitPublicSourceDirs = source.readStringArray(); splitDependencies = source.readSparseArray(null); - nativeLibraryDir = source.readString(); - secondaryNativeLibraryDir = source.readString(); - nativeLibraryRootDir = source.readString(); + nativeLibraryDir = source.readString8(); + secondaryNativeLibraryDir = source.readString8(); + nativeLibraryRootDir = source.readString8(); nativeLibraryRootRequiresIsa = source.readInt() != 0; - primaryCpuAbi = source.readString(); - secondaryCpuAbi = source.readString(); + primaryCpuAbi = source.readString8(); + secondaryCpuAbi = source.readString8(); resourceDirs = source.readStringArray(); - seInfo = source.readString(); - seInfoUser = source.readString(); + seInfo = source.readString8(); + seInfoUser = source.readString8(); sharedLibraryFiles = source.readStringArray(); sharedLibraryInfos = source.createTypedArrayList(SharedLibraryInfo.CREATOR); - dataDir = source.readString(); - deviceProtectedDataDir = source.readString(); - credentialProtectedDataDir = source.readString(); + dataDir = source.readString8(); + deviceProtectedDataDir = source.readString8(); + credentialProtectedDataDir = source.readString8(); uid = source.readInt(); minSdkVersion = source.readInt(); targetSdkVersion = source.readInt(); @@ -1831,8 +1831,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { enabled = source.readInt() != 0; enabledSetting = source.readInt(); installLocation = source.readInt(); - manageSpaceActivityName = source.readString(); - backupAgentName = source.readString(); + manageSpaceActivityName = source.readString8(); + backupAgentName = source.readString8(); descriptionRes = source.readInt(); uiOptions = source.readInt(); fullBackupContent = source.readInt(); @@ -1840,16 +1840,16 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { networkSecurityConfigRes = source.readInt(); category = source.readInt(); targetSandboxVersion = source.readInt(); - classLoaderName = source.readString(); + classLoaderName = source.readString8(); splitClassLoaderNames = source.readStringArray(); compileSdkVersion = source.readInt(); - compileSdkVersionCodename = source.readString(); - appComponentFactory = source.readString(); + compileSdkVersionCodename = source.readString8(); + appComponentFactory = source.readString8(); iconRes = source.readInt(); roundIconRes = source.readInt(); mHiddenApiPolicy = source.readInt(); hiddenUntilInstalled = source.readInt() != 0; - zygotePreloadName = source.readString(); + zygotePreloadName = source.readString8(); gwpAsanMode = source.readInt(); } diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java index 362098c447ce..628bcd70cdf6 100644 --- a/core/java/android/content/pm/ComponentInfo.java +++ b/core/java/android/content/pm/ComponentInfo.java @@ -197,8 +197,8 @@ public class ComponentInfo extends PackageItemInfo { public void writeToParcel(Parcel dest, int parcelableFlags) { super.writeToParcel(dest, parcelableFlags); applicationInfo.writeToParcel(dest, parcelableFlags); - dest.writeString(processName); - dest.writeString(splitName); + dest.writeString8(processName); + dest.writeString8(splitName); dest.writeInt(descriptionRes); dest.writeInt(enabled ? 1 : 0); dest.writeInt(exported ? 1 : 0); @@ -208,8 +208,8 @@ public class ComponentInfo extends PackageItemInfo { protected ComponentInfo(Parcel source) { super(source); applicationInfo = ApplicationInfo.CREATOR.createFromParcel(source); - processName = source.readString(); - splitName = source.readString(); + processName = source.readString8(); + splitName = source.readString8(); descriptionRes = source.readInt(); enabled = (source.readInt() != 0); exported = (source.readInt() != 0); diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java index 144a07eb4ea3..99e6d91a61ae 100644 --- a/core/java/android/content/pm/CrossProfileApps.java +++ b/core/java/android/content/pm/CrossProfileApps.java @@ -279,12 +279,8 @@ public class CrossProfileApps { * <ul> * <li>{@code UserManager#getEnabledProfileIds(int)} ()} returns at least one other profile for * the calling user.</li> - * <li>The calling app has requested</li> - * {@code android.Manifest.permission.INTERACT_ACROSS_PROFILES} in its manifest. - * <li>The calling package has either been whitelisted by default by the OEM or has been - * explicitly whitelisted by the admin via - * {@link android.app.admin.DevicePolicyManager#setCrossProfilePackages(ComponentName, Set)}. - * </li> + * <li>The calling app has requested + * {@code android.Manifest.permission.INTERACT_ACROSS_PROFILES} in its manifest.</li> * </ul> * * <p>Note that in order for the user to be able to grant the consent, the requesting package diff --git a/core/java/android/content/pm/DataLoaderManager.java b/core/java/android/content/pm/DataLoaderManager.java index 4a6193888685..e8fb2413bbbe 100644 --- a/core/java/android/content/pm/DataLoaderManager.java +++ b/core/java/android/content/pm/DataLoaderManager.java @@ -41,17 +41,16 @@ public class DataLoaderManager { * @param dataLoaderId ID for the new data loader binder service. * @param params DataLoaderParamsParcel object that contains data loader params, including * its package name, class name, and additional parameters. - * @param control FileSystemControlParcel that contains filesystem control handlers. * @param listener Callback for the data loader service to report status back to the * caller. * @return false if 1) target ID collides with a data loader that is already bound to data * loader manager; 2) package name is not specified; 3) fails to find data loader package; * or 4) fails to bind to the specified data loader service, otherwise return true. */ - public boolean initializeDataLoader(int dataLoaderId, @NonNull DataLoaderParamsParcel params, - @NonNull FileSystemControlParcel control, @NonNull IDataLoaderStatusListener listener) { + public boolean bindToDataLoader(int dataLoaderId, @NonNull DataLoaderParamsParcel params, + @NonNull IDataLoaderStatusListener listener) { try { - return mService.initializeDataLoader(dataLoaderId, params, control, listener); + return mService.bindToDataLoader(dataLoaderId, params, listener); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -70,12 +69,13 @@ public class DataLoaderManager { } /** - * Destroys the data loader binder service and removes it from data loader manager service. + * Unbinds from a data loader binder service, specified by its ID. + * DataLoader will receive destroy notification. */ @Nullable - public void destroyDataLoader(int dataLoaderId) { + public void unbindFromDataLoader(int dataLoaderId) { try { - mService.destroyDataLoader(dataLoaderId); + mService.unbindFromDataLoader(dataLoaderId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/content/pm/FeatureInfo.java b/core/java/android/content/pm/FeatureInfo.java index 9f3ab77062ef..89269e0d7aa5 100644 --- a/core/java/android/content/pm/FeatureInfo.java +++ b/core/java/android/content/pm/FeatureInfo.java @@ -108,7 +108,7 @@ public class FeatureInfo implements Parcelable { @Override public void writeToParcel(Parcel dest, int parcelableFlags) { - dest.writeString(name); + dest.writeString8(name); dest.writeInt(version); dest.writeInt(reqGlEsVersion); dest.writeInt(flags); @@ -138,7 +138,7 @@ public class FeatureInfo implements Parcelable { }; private FeatureInfo(Parcel source) { - name = source.readString(); + name = source.readString8(); version = source.readInt(); reqGlEsVersion = source.readInt(); flags = source.readInt(); diff --git a/core/java/android/content/pm/IDataLoaderManager.aidl b/core/java/android/content/pm/IDataLoaderManager.aidl index 1336f7229ee7..93b3de7897c4 100644 --- a/core/java/android/content/pm/IDataLoaderManager.aidl +++ b/core/java/android/content/pm/IDataLoaderManager.aidl @@ -23,8 +23,8 @@ import android.content.pm.IDataLoaderStatusListener; /** @hide */ interface IDataLoaderManager { - boolean initializeDataLoader(int id, in DataLoaderParamsParcel params, - in FileSystemControlParcel control, IDataLoaderStatusListener listener); + boolean bindToDataLoader(int id, in DataLoaderParamsParcel params, + IDataLoaderStatusListener listener); IDataLoader getDataLoader(int dataLoaderId); - void destroyDataLoader(int dataLoaderId); -}
\ No newline at end of file + void unbindFromDataLoader(int dataLoaderId); +} diff --git a/core/java/android/content/pm/IDataLoaderStatusListener.aidl b/core/java/android/content/pm/IDataLoaderStatusListener.aidl index 9819b5d4eeb9..24a62c5638ec 100644 --- a/core/java/android/content/pm/IDataLoaderStatusListener.aidl +++ b/core/java/android/content/pm/IDataLoaderStatusListener.aidl @@ -21,17 +21,30 @@ package android.content.pm; * @hide */ oneway interface IDataLoaderStatusListener { - /** Data loader status */ - const int DATA_LOADER_CREATED = 0; - const int DATA_LOADER_DESTROYED = 1; + /** The DataLoader process died, binder disconnected or class destroyed. */ + const int DATA_LOADER_DESTROYED = 0; + /** DataLoader process is running and bound to. */ + const int DATA_LOADER_BOUND = 1; + /** DataLoader has handled onCreate(). */ + const int DATA_LOADER_CREATED = 2; - const int DATA_LOADER_STARTED = 2; - const int DATA_LOADER_STOPPED = 3; + /** DataLoader can receive missing pages and read pages notifications, + * and ready to provide data. */ + const int DATA_LOADER_STARTED = 3; + /** DataLoader no longer ready to provide data and is not receiving + * any notifications from IncFS. */ + const int DATA_LOADER_STOPPED = 4; - const int DATA_LOADER_IMAGE_READY = 4; - const int DATA_LOADER_IMAGE_NOT_READY = 5; + /** DataLoader streamed everything necessary to continue installation. */ + const int DATA_LOADER_IMAGE_READY = 5; + /** Installation can't continue as DataLoader failed to stream necessary data. */ + const int DATA_LOADER_IMAGE_NOT_READY = 6; - const int DATA_LOADER_UNRECOVERABLE = 6; + /** DataLoader reports that this instance is invalid and can never be restored. + * Warning: this is a terminal status that data loader should use carefully and + * the system should almost never use - e.g. only if all recovery attempts + * fail and all retry limits are exceeded. */ + const int DATA_LOADER_UNRECOVERABLE = 7; /** Data loader status callback */ void onStatusChanged(in int dataLoaderId, in int status); diff --git a/core/java/android/content/pm/InstrumentationInfo.java b/core/java/android/content/pm/InstrumentationInfo.java index 574a1ee2d0ce..745a6c1a0dff 100644 --- a/core/java/android/content/pm/InstrumentationInfo.java +++ b/core/java/android/content/pm/InstrumentationInfo.java @@ -157,21 +157,21 @@ public class InstrumentationInfo extends PackageItemInfo implements Parcelable { public void writeToParcel(Parcel dest, int parcelableFlags) { super.writeToParcel(dest, parcelableFlags); - dest.writeString(targetPackage); - dest.writeString(targetProcesses); - dest.writeString(sourceDir); - dest.writeString(publicSourceDir); + dest.writeString8(targetPackage); + dest.writeString8(targetProcesses); + dest.writeString8(sourceDir); + dest.writeString8(publicSourceDir); dest.writeStringArray(splitNames); dest.writeStringArray(splitSourceDirs); dest.writeStringArray(splitPublicSourceDirs); dest.writeSparseArray((SparseArray) splitDependencies); - dest.writeString(dataDir); - dest.writeString(deviceProtectedDataDir); - dest.writeString(credentialProtectedDataDir); - dest.writeString(primaryCpuAbi); - dest.writeString(secondaryCpuAbi); - dest.writeString(nativeLibraryDir); - dest.writeString(secondaryNativeLibraryDir); + dest.writeString8(dataDir); + dest.writeString8(deviceProtectedDataDir); + dest.writeString8(credentialProtectedDataDir); + dest.writeString8(primaryCpuAbi); + dest.writeString8(secondaryCpuAbi); + dest.writeString8(nativeLibraryDir); + dest.writeString8(secondaryNativeLibraryDir); dest.writeInt((handleProfiling == false) ? 0 : 1); dest.writeInt((functionalTest == false) ? 0 : 1); } @@ -189,21 +189,21 @@ public class InstrumentationInfo extends PackageItemInfo implements Parcelable { @SuppressWarnings("unchecked") private InstrumentationInfo(Parcel source) { super(source); - targetPackage = source.readString(); - targetProcesses = source.readString(); - sourceDir = source.readString(); - publicSourceDir = source.readString(); + targetPackage = source.readString8(); + targetProcesses = source.readString8(); + sourceDir = source.readString8(); + publicSourceDir = source.readString8(); splitNames = source.readStringArray(); splitSourceDirs = source.readStringArray(); splitPublicSourceDirs = source.readStringArray(); splitDependencies = source.readSparseArray(null); - dataDir = source.readString(); - deviceProtectedDataDir = source.readString(); - credentialProtectedDataDir = source.readString(); - primaryCpuAbi = source.readString(); - secondaryCpuAbi = source.readString(); - nativeLibraryDir = source.readString(); - secondaryNativeLibraryDir = source.readString(); + dataDir = source.readString8(); + deviceProtectedDataDir = source.readString8(); + credentialProtectedDataDir = source.readString8(); + primaryCpuAbi = source.readString8(); + secondaryCpuAbi = source.readString8(); + nativeLibraryDir = source.readString8(); + secondaryNativeLibraryDir = source.readString8(); handleProfiling = source.readInt() != 0; functionalTest = source.readInt() != 0; } diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index 85c698f3fb0c..bb56ef7fd3a0 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -441,14 +441,14 @@ public class PackageInfo implements Parcelable { public void writeToParcel(Parcel dest, int parcelableFlags) { // Allow ApplicationInfo to be squashed. final boolean prevAllowSquashing = dest.allowSquashing(); - dest.writeString(packageName); + dest.writeString8(packageName); dest.writeStringArray(splitNames); dest.writeInt(versionCode); dest.writeInt(versionCodeMajor); - dest.writeString(versionName); + dest.writeString8(versionName); dest.writeInt(baseRevisionCode); dest.writeIntArray(splitRevisionCodes); - dest.writeString(sharedUserId); + dest.writeString8(sharedUserId); dest.writeInt(sharedUserLabel); if (applicationInfo != null) { dest.writeInt(1); @@ -475,14 +475,14 @@ public class PackageInfo implements Parcelable { dest.writeInt(isStub ? 1 : 0); dest.writeInt(coreApp ? 1 : 0); dest.writeInt(requiredForAllUsers ? 1 : 0); - dest.writeString(restrictedAccountType); - dest.writeString(requiredAccountType); - dest.writeString(overlayTarget); - dest.writeString(overlayCategory); + dest.writeString8(restrictedAccountType); + dest.writeString8(requiredAccountType); + dest.writeString8(overlayTarget); + dest.writeString8(overlayCategory); dest.writeInt(overlayPriority); dest.writeBoolean(mOverlayIsStatic); dest.writeInt(compileSdkVersion); - dest.writeString(compileSdkVersionCodename); + dest.writeString8(compileSdkVersionCodename); if (signingInfo != null) { dest.writeInt(1); signingInfo.writeToParcel(dest, parcelableFlags); @@ -508,14 +508,14 @@ public class PackageInfo implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private PackageInfo(Parcel source) { - packageName = source.readString(); + packageName = source.readString8(); splitNames = source.createStringArray(); versionCode = source.readInt(); versionCodeMajor = source.readInt(); - versionName = source.readString(); + versionName = source.readString8(); baseRevisionCode = source.readInt(); splitRevisionCodes = source.createIntArray(); - sharedUserId = source.readString(); + sharedUserId = source.readString8(); sharedUserLabel = source.readInt(); int hasApp = source.readInt(); if (hasApp != 0) { @@ -540,14 +540,14 @@ public class PackageInfo implements Parcelable { isStub = source.readInt() != 0; coreApp = source.readInt() != 0; requiredForAllUsers = source.readInt() != 0; - restrictedAccountType = source.readString(); - requiredAccountType = source.readString(); - overlayTarget = source.readString(); - overlayCategory = source.readString(); + restrictedAccountType = source.readString8(); + requiredAccountType = source.readString8(); + overlayTarget = source.readString8(); + overlayCategory = source.readString8(); overlayPriority = source.readInt(); mOverlayIsStatic = source.readBoolean(); compileSdkVersion = source.readInt(); - compileSdkVersionCodename = source.readString(); + compileSdkVersionCodename = source.readString8(); int hasSigningInfo = source.readInt(); if (hasSigningInfo != 0) { signingInfo = SigningInfo.CREATOR.createFromParcel(source); diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java index 7fd5531bf20d..d41ace5bcf62 100644 --- a/core/java/android/content/pm/PackageItemInfo.java +++ b/core/java/android/content/pm/PackageItemInfo.java @@ -422,8 +422,8 @@ public class PackageItemInfo { } public void writeToParcel(Parcel dest, int parcelableFlags) { - dest.writeString(name); - dest.writeString(packageName); + dest.writeString8(name); + dest.writeString8(packageName); dest.writeInt(labelRes); TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags); dest.writeInt(icon); @@ -452,8 +452,8 @@ public class PackageItemInfo { } protected PackageItemInfo(Parcel source) { - name = source.readString(); - packageName = source.readString(); + name = source.readString8(); + packageName = source.readString8(); labelRes = source.readInt(); nonLocalizedLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 85bafd9d37e2..8a57f826ad2e 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -6873,9 +6873,9 @@ public class PackageParser { /** @hide */ public boolean canHaveOatDir() { - // The following app types CANNOT have oat directory - // - non-updated system apps - return !isSystem() || isUpdatedSystemApp(); + // Nobody should be calling this method ever, but we can't rely on this. + // Thus no logic here and a reasonable return value. + return true; } public boolean isMatch(int flags) { diff --git a/core/java/android/content/pm/PackageParserCacheHelper.java b/core/java/android/content/pm/PackageParserCacheHelper.java index 44def3321c34..8212224e114c 100644 --- a/core/java/android/content/pm/PackageParserCacheHelper.java +++ b/core/java/android/content/pm/PackageParserCacheHelper.java @@ -78,10 +78,19 @@ public class PackageParserCacheHelper { /** * Read an string index from a parcel, and returns the corresponding string from the pool. */ - @Override public String readString(Parcel p) { return mStrings.get(p.readInt()); } + + @Override + public String readString8(Parcel p) { + return readString(p); + } + + @Override + public String readString16(Parcel p) { + return readString(p); + } } /** @@ -110,7 +119,6 @@ public class PackageParserCacheHelper { * Instead of writing a string directly to a parcel, this method adds it to the pool, * and write the index in the pool to the parcel. */ - @Override public void writeString(Parcel p, String s) { final Integer cur = mIndexes.get(s); if (cur != null) { @@ -133,6 +141,16 @@ public class PackageParserCacheHelper { } } + @Override + public void writeString8(Parcel p, String s) { + writeString(p, s); + } + + @Override + public void writeString16(Parcel p, String s) { + writeString(p, s); + } + /** * Closes a parcel by appending the string pool at the end and updating the pool offset, * which it assumes is at the first byte. It also uninstalls itself as a read-write helper. diff --git a/core/java/android/content/pm/ProviderInfo.java b/core/java/android/content/pm/ProviderInfo.java index 07d42dc823c4..3984ade73d6c 100644 --- a/core/java/android/content/pm/ProviderInfo.java +++ b/core/java/android/content/pm/ProviderInfo.java @@ -145,9 +145,9 @@ public final class ProviderInfo extends ComponentInfo @Override public void writeToParcel(Parcel out, int parcelableFlags) { super.writeToParcel(out, parcelableFlags); - out.writeString(authority); - out.writeString(readPermission); - out.writeString(writePermission); + out.writeString8(authority); + out.writeString8(readPermission); + out.writeString8(writePermission); out.writeInt(grantUriPermissions ? 1 : 0); out.writeInt(forceUriPermissions ? 1 : 0); out.writeTypedArray(uriPermissionPatterns, parcelableFlags); @@ -175,9 +175,9 @@ public final class ProviderInfo extends ComponentInfo private ProviderInfo(Parcel in) { super(in); - authority = in.readString(); - readPermission = in.readString(); - writePermission = in.readString(); + authority = in.readString8(); + readPermission = in.readString8(); + writePermission = in.readString8(); grantUriPermissions = in.readInt() != 0; forceUriPermissions = in.readInt() != 0; uriPermissionPatterns = in.createTypedArray(PatternMatcher.CREATOR); diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java index 5f90b6c43c60..d3f9e2486a64 100644 --- a/core/java/android/content/pm/ServiceInfo.java +++ b/core/java/android/content/pm/ServiceInfo.java @@ -244,7 +244,7 @@ public class ServiceInfo extends ComponentInfo public void writeToParcel(Parcel dest, int parcelableFlags) { super.writeToParcel(dest, parcelableFlags); - dest.writeString(permission); + dest.writeString8(permission); dest.writeInt(flags); dest.writeInt(mForegroundServiceType); } @@ -261,7 +261,7 @@ public class ServiceInfo extends ComponentInfo private ServiceInfo(Parcel source) { super(source); - permission = source.readString(); + permission = source.readString8(); flags = source.readInt(); mForegroundServiceType = source.readInt(); } diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 88f4c31b82cc..4e189796bc48 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -1530,8 +1530,8 @@ public class ParsingPackageUtils { } else if (parser.getName().equals("package")) { final TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestQueriesPackage); - final String packageName = sa.getString( - R.styleable.AndroidManifestQueriesPackage_name); + final String packageName = sa.getNonConfigurationString( + R.styleable.AndroidManifestQueriesPackage_name, 0); if (TextUtils.isEmpty(packageName)) { return input.error("Package name is missing from package tag."); } @@ -1540,8 +1540,8 @@ public class ParsingPackageUtils { final TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestQueriesProvider); try { - final String authorities = - sa.getString(R.styleable.AndroidManifestQueriesProvider_authorities); + final String authorities = sa.getNonConfigurationString( + R.styleable.AndroidManifestQueriesProvider_authorities, 0); if (TextUtils.isEmpty(authorities)) { return input.error( PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java index f7c96a3a02c1..2f67f6ddc082 100644 --- a/core/java/android/database/sqlite/SQLiteConnection.java +++ b/core/java/android/database/sqlite/SQLiteConnection.java @@ -228,19 +228,26 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } catch (SQLiteCantOpenDatabaseException e) { String message = String.format("Cannot open database '%s'", file); - final Path path = FileSystems.getDefault().getPath(file); - final Path dir = path.getParent(); - - if (!Files.isDirectory(dir)) { - message += ": Directory " + dir + " doesn't exist"; - } else if (!Files.exists(path)) { - message += ": File " + path + " doesn't exist"; - } else if (!Files.isReadable(path)) { - message += ": File " + path + " is not readable"; - } else if (Files.isDirectory(path)) { - message += ": Path " + path + " is a directory"; - } else { - message += ": Unknown reason"; + try { + // Try to diagnose for common reasons. If something fails in here, that's fine; + // just swallow the exception. + + final Path path = FileSystems.getDefault().getPath(file); + final Path dir = path.getParent(); + + if (!Files.isDirectory(dir)) { + message += ": Directory " + dir + " doesn't exist"; + } else if (!Files.exists(path)) { + message += ": File " + path + " doesn't exist"; + } else if (!Files.isReadable(path)) { + message += ": File " + path + " is not readable"; + } else if (Files.isDirectory(path)) { + message += ": Path " + path + " is a directory"; + } else { + message += ": Unknown reason"; + } + } catch (Throwable th) { + message += ": Unknown reason; cannot examine filesystem: " + th.getMessage(); } throw new SQLiteCantOpenDatabaseException(message, e); } finally { diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index eb6901f6650e..20120394d1e9 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -488,11 +488,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * The respective value of such request key can be obtained by calling * {@link CaptureRequest.Builder#getPhysicalCameraKey }. Capture requests that contain * individual physical device requests must be built via - * {@link android.hardware.camera2.CameraDevice#createCaptureRequest(int, Set)}. - * Such extended capture requests can be passed only to - * {@link CameraCaptureSession#capture } or {@link CameraCaptureSession#captureBurst } and - * not to {@link CameraCaptureSession#setRepeatingRequest } or - * {@link CameraCaptureSession#setRepeatingBurst }.</p> + * {@link android.hardware.camera2.CameraDevice#createCaptureRequest(int, Set)}.</p> * * <p>The list returned is not modifiable, so any attempts to modify it will throw * a {@code UnsupportedOperationException}.</p> diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index 462110f5a795..ad9bf0745779 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -65,21 +65,23 @@ public abstract class DisplayManagerInternal { public abstract boolean isProximitySensorAvailable(); /** - * Take a screenshot of the specified display and return a buffer. + * Screenshot for internal system-only use such as rotation, etc. This method includes + * secure layers and the result should never be exposed to non-system applications. + * This method does not apply any rotation and provides the output in natural orientation. * * @param displayId The display id to take the screenshot of. * @return The buffer or null if we have failed. */ - public abstract SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId); + public abstract SurfaceControl.ScreenshotGraphicBuffer systemScreenshot(int displayId); /** - * Take a screenshot without secure layer of the specified display and return a buffer. + * General screenshot functionality that excludes secure layers and applies appropriate + * rotation that the device is currently in. * * @param displayId The display id to take the screenshot of. * @return The buffer or null if we have failed. */ - public abstract SurfaceControl.ScreenshotGraphicBuffer screenshotWithoutSecureLayer( - int displayId); + public abstract SurfaceControl.ScreenshotGraphicBuffer userScreenshot(int displayId); /** * Returns information about the specified logical display. diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java index 525bbfdbb06d..1cb4fe8cf4e7 100644 --- a/core/java/android/net/Uri.java +++ b/core/java/android/net/Uri.java @@ -500,7 +500,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { } static Uri readFrom(Parcel parcel) { - return new StringUri(parcel.readString()); + return new StringUri(parcel.readString8()); } public int describeContents() { @@ -509,7 +509,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(TYPE_ID); - parcel.writeString(uriString); + parcel.writeString8(uriString); } /** Cached scheme separator index. */ @@ -875,7 +875,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { static Uri readFrom(Parcel parcel) { return new OpaqueUri( - parcel.readString(), + parcel.readString8(), Part.readFrom(parcel), Part.readFrom(parcel) ); @@ -887,7 +887,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(TYPE_ID); - parcel.writeString(scheme); + parcel.writeString8(scheme); ssp.writeTo(parcel); fragment.writeTo(parcel); } @@ -1195,7 +1195,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { static Uri readFrom(Parcel parcel) { return new HierarchicalUri( - parcel.readString(), + parcel.readString8(), Part.readFrom(parcel), PathPart.readFrom(parcel), Part.readFrom(parcel), @@ -1209,7 +1209,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(TYPE_ID); - parcel.writeString(scheme); + parcel.writeString8(scheme); authority.writeTo(parcel); path.writeTo(parcel); query.writeTo(parcel); @@ -2028,7 +2028,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { + mCanonicalRepresentation + ")"); } parcel.writeInt(mCanonicalRepresentation); - parcel.writeString(canonicalValue); + parcel.writeString8(canonicalValue); } } @@ -2060,7 +2060,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { static Part readFrom(Parcel parcel) { int representation = parcel.readInt(); - String value = parcel.readString(); + String value = parcel.readString8(); switch (representation) { case REPRESENTATION_ENCODED: return fromEncoded(value); @@ -2251,9 +2251,9 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { int representation = parcel.readInt(); switch (representation) { case REPRESENTATION_ENCODED: - return fromEncoded(parcel.readString()); + return fromEncoded(parcel.readString8()); case REPRESENTATION_DECODED: - return fromDecoded(parcel.readString()); + return fromDecoded(parcel.readString8()); default: throw new IllegalArgumentException("Unknown representation: " + representation); } diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index f0b7b5fa5a1a..93f6607ff9d4 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -307,7 +307,9 @@ public final class Parcel { @FastNative private static native void nativeWriteDouble(long nativePtr, double val); @FastNative - static native void nativeWriteString(long nativePtr, String val); + private static native void nativeWriteString8(long nativePtr, String val); + @FastNative + private static native void nativeWriteString16(long nativePtr, String val); @FastNative private static native void nativeWriteStrongBinder(long nativePtr, IBinder val); @FastNative @@ -325,7 +327,9 @@ public final class Parcel { @CriticalNative private static native double nativeReadDouble(long nativePtr); @FastNative - static native String nativeReadString(long nativePtr); + private static native String nativeReadString8(long nativePtr); + @FastNative + private static native String nativeReadString16(long nativePtr); @FastNative private static native IBinder nativeReadStrongBinder(long nativePtr); @FastNative @@ -386,8 +390,12 @@ public final class Parcel { * must use {@link #writeStringNoHelper(String)} to avoid * infinity recursive calls. */ - public void writeString(Parcel p, String s) { - nativeWriteString(p.mNativePtr, s); + public void writeString8(Parcel p, String s) { + p.writeString8NoHelper(s); + } + + public void writeString16(Parcel p, String s) { + p.writeString16NoHelper(s); } /** @@ -395,8 +403,12 @@ public final class Parcel { * must use {@link #readStringNoHelper()} to avoid * infinity recursive calls. */ - public String readString(Parcel p) { - return nativeReadString(p.mNativePtr); + public String readString8(Parcel p) { + return p.readString8NoHelper(); + } + + public String readString16(Parcel p) { + return p.readString16NoHelper(); } } @@ -759,7 +771,17 @@ public final class Parcel { * growing dataCapacity() if needed. */ public final void writeString(@Nullable String val) { - mReadWriteHelper.writeString(this, val); + writeString16(val); + } + + /** {@hide} */ + public final void writeString8(@Nullable String val) { + mReadWriteHelper.writeString8(this, val); + } + + /** {@hide} */ + public final void writeString16(@Nullable String val) { + mReadWriteHelper.writeString16(this, val); } /** @@ -770,7 +792,17 @@ public final class Parcel { * @hide */ public void writeStringNoHelper(@Nullable String val) { - nativeWriteString(mNativePtr, val); + writeString16NoHelper(val); + } + + /** {@hide} */ + public void writeString8NoHelper(@Nullable String val) { + nativeWriteString8(mNativePtr, val); + } + + /** {@hide} */ + public void writeString16NoHelper(@Nullable String val) { + nativeWriteString16(mNativePtr, val); } /** @@ -2337,7 +2369,17 @@ public final class Parcel { */ @Nullable public final String readString() { - return mReadWriteHelper.readString(this); + return readString16(); + } + + /** {@hide} */ + public final @Nullable String readString8() { + return mReadWriteHelper.readString8(this); + } + + /** {@hide} */ + public final @Nullable String readString16() { + return mReadWriteHelper.readString16(this); } /** @@ -2347,9 +2389,18 @@ public final class Parcel { * * @hide */ - @Nullable - public String readStringNoHelper() { - return nativeReadString(mNativePtr); + public @Nullable String readStringNoHelper() { + return readString16NoHelper(); + } + + /** {@hide} */ + public @Nullable String readString8NoHelper() { + return nativeReadString8(mNativePtr); + } + + /** {@hide} */ + public @Nullable String readString16NoHelper() { + return nativeReadString16(mNativePtr); } /** diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java index 251995a14090..321dc9e2246e 100644 --- a/core/java/android/os/incremental/IncrementalFileStorages.java +++ b/core/java/android/os/incremental/IncrementalFileStorages.java @@ -38,16 +38,10 @@ import android.content.pm.DataLoaderParams; import android.content.pm.IDataLoaderStatusListener; import android.content.pm.InstallationFileParcel; import android.text.TextUtils; -import android.util.Slog; import java.io.File; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; -import java.util.Objects; -import java.util.Random; /** * This class manages storage instances used during a package installation session. @@ -56,13 +50,9 @@ import java.util.Random; public final class IncrementalFileStorages { private static final String TAG = "IncrementalFileStorages"; - private static final String TMP_DIR_ROOT = "/data/incremental/tmp"; - private static final Random TMP_DIR_RANDOM = new Random(); - + private @NonNull final IncrementalManager mIncrementalManager; + private @NonNull final File mStageDir; private @Nullable IncrementalStorage mDefaultStorage; - private @Nullable String mDefaultDir; - private @NonNull IncrementalManager mIncrementalManager; - private @NonNull File mStageDir; /** * Set up files and directories used in an installation session. Only used by Incremental. @@ -85,72 +75,63 @@ public final class IncrementalFileStorages { throw new IOException("Failed to obtain incrementalManager."); } - IncrementalFileStorages result = null; - try { - result = new IncrementalFileStorages(stageDir, incrementalManager, dataLoaderParams, - dataLoaderStatusListener); - - if (!addedFiles.isEmpty()) { - result.mDefaultStorage.bind(stageDir.getAbsolutePath()); - } - - for (InstallationFileParcel file : addedFiles) { - if (file.location == LOCATION_DATA_APP) { - try { - result.addApkFile(file); - } catch (IOException e) { - // TODO(b/146080380): add incremental-specific error code - throw new IOException( - "Failed to add file to IncFS: " + file.name + ", reason: ", e); - } - } else { - throw new IOException("Unknown file location: " + file.location); + final IncrementalFileStorages result = + new IncrementalFileStorages(stageDir, incrementalManager, dataLoaderParams, + dataLoaderStatusListener); + for (InstallationFileParcel file : addedFiles) { + if (file.location == LOCATION_DATA_APP) { + try { + result.addApkFile(file); + } catch (IOException e) { + // TODO(b/146080380): add incremental-specific error code + throw new IOException( + "Failed to add file to IncFS: " + file.name + ", reason: ", e); } + } else { + throw new IOException("Unknown file location: " + file.location); } + } - // TODO(b/146080380): remove 5 secs wait in startLoading - if (!result.mDefaultStorage.startLoading()) { - // TODO(b/146080380): add incremental-specific error code - throw new IOException("Failed to start loading data for Incremental installation."); - } - - return result; - } catch (IOException e) { - Slog.e(TAG, "Failed to initialize Incremental file storages. Cleaning up...", e); - if (result != null) { - result.cleanUp(); - } - throw e; + if (!result.mDefaultStorage.startLoading()) { + // TODO(b/146080380): add incremental-specific error code + throw new IOException("Failed to start loading data for Incremental installation."); } + + return result; } private IncrementalFileStorages(@NonNull File stageDir, @NonNull IncrementalManager incrementalManager, @NonNull DataLoaderParams dataLoaderParams, @Nullable IDataLoaderStatusListener dataLoaderStatusListener) throws IOException { - mStageDir = stageDir; - mIncrementalManager = incrementalManager; - if (dataLoaderParams.getComponentName().getPackageName().equals("local")) { - final String incrementalPath = dataLoaderParams.getArguments(); - mDefaultDir = incrementalPath; - if (TextUtils.isEmpty(mDefaultDir)) { - throw new IOException("Failed to create storage: incrementalPath is empty"); - } - mDefaultStorage = mIncrementalManager.openStorage(incrementalPath); - } else { - mDefaultDir = getTempDir(); - if (mDefaultDir == null) { - throw new IOException("Failed to create storage: tempDir is empty"); + try { + mStageDir = stageDir; + mIncrementalManager = incrementalManager; + if (dataLoaderParams.getComponentName().getPackageName().equals("local")) { + final String incrementalPath = dataLoaderParams.getArguments(); + if (TextUtils.isEmpty(incrementalPath)) { + throw new IOException("Failed to create storage: incrementalPath is empty"); + } + mDefaultStorage = mIncrementalManager.openStorage(incrementalPath); + if (mDefaultStorage == null) { + throw new IOException( + "Couldn't open incremental storage at " + incrementalPath); + } + mDefaultStorage.bind(stageDir.getAbsolutePath()); + } else { + mDefaultStorage = mIncrementalManager.createStorage(stageDir.getAbsolutePath(), + dataLoaderParams, + dataLoaderStatusListener, + IncrementalManager.CREATE_MODE_CREATE + | IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false); + if (mDefaultStorage == null) { + throw new IOException( + "Couldn't create incremental storage at " + stageDir); + } } - mDefaultStorage = mIncrementalManager.createStorage(mDefaultDir, - dataLoaderParams, - dataLoaderStatusListener, - IncrementalManager.CREATE_MODE_CREATE - | IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false); - } - - if (mDefaultStorage == null) { - throw new IOException("Failed to create storage"); + } catch (IOException e) { + cleanUp(); + throw e; } } @@ -167,27 +148,14 @@ public final class IncrementalFileStorages { * TODO(b/136132412): make sure unnecessary binds are removed but useful storages are kept */ public void cleanUp() { - Objects.requireNonNull(mDefaultStorage); + if (mDefaultStorage == null) { + return; + } try { - mDefaultStorage.unBind(mDefaultDir); mDefaultStorage.unBind(mStageDir.getAbsolutePath()); } catch (IOException ignored) { } - - mDefaultDir = null; mDefaultStorage = null; } - - private static String getTempDir() { - final Path tmpDir = Paths.get(TMP_DIR_ROOT, - String.valueOf(TMP_DIR_RANDOM.nextInt(Integer.MAX_VALUE - 1))); - try { - Files.createDirectories(tmpDir); - } catch (Exception ex) { - Slog.e(TAG, "Failed to create dir", ex); - return null; - } - return tmpDir.toAbsolutePath().toString(); - } } diff --git a/core/java/android/os/incremental/IncrementalManager.java b/core/java/android/os/incremental/IncrementalManager.java index 35518db32829..916edfae679f 100644 --- a/core/java/android/os/incremental/IncrementalManager.java +++ b/core/java/android/os/incremental/IncrementalManager.java @@ -32,8 +32,12 @@ import java.io.File; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; /** * Provides operations to open or create an IncrementalStorage, using IIncrementalService @@ -176,25 +180,6 @@ public final class IncrementalManager { } /** - * Iterates through path parents to find the base dir of an Incremental Storage. - * - * @param file Target file to search storage for. - * @return Absolute path which is a bind-mount point of Incremental File System. - */ - @Nullable - private Path getStoragePathForFile(File file) { - File currentPath = new File(file.getParent()); - while (currentPath.getParent() != null) { - IncrementalStorage storage = openStorage(currentPath.getAbsolutePath()); - if (storage != null) { - return currentPath.toPath(); - } - currentPath = new File(currentPath.getParent()); - } - return null; - } - - /** * Set up an app's code path. The expected outcome of this method is: * 1) The actual apk directory under /data/incremental is bind-mounted to the parent directory * of {@code afterCodeFile}. @@ -212,29 +197,27 @@ public final class IncrementalManager { */ public void renameCodePath(File beforeCodeFile, File afterCodeFile) throws IllegalArgumentException, IOException { - final String beforeCodePath = beforeCodeFile.getAbsolutePath(); - final String afterCodePathParent = afterCodeFile.getParentFile().getAbsolutePath(); - if (!isIncrementalPath(beforeCodePath)) { - throw new IllegalArgumentException("Not an Incremental path: " + beforeCodePath); - } - final String afterCodePathName = afterCodeFile.getName(); - final Path apkStoragePath = Paths.get(beforeCodePath); - if (apkStoragePath == null || apkStoragePath.toAbsolutePath() == null) { - throw new IOException("Invalid source storage path for: " + beforeCodePath); - } - final IncrementalStorage apkStorage = - openStorage(apkStoragePath.toAbsolutePath().toString()); + final File beforeCodeAbsolute = beforeCodeFile.getAbsoluteFile(); + final IncrementalStorage apkStorage = openStorage(beforeCodeAbsolute.toString()); if (apkStorage == null) { - throw new IOException("Failed to retrieve storage from Incremental Service."); + throw new IllegalArgumentException("Not an Incremental path: " + beforeCodeAbsolute); } - final IncrementalStorage linkedApkStorage = createStorage(afterCodePathParent, apkStorage, - IncrementalManager.CREATE_MODE_CREATE - | IncrementalManager.CREATE_MODE_PERMANENT_BIND); + final String targetStorageDir = afterCodeFile.getAbsoluteFile().getParent(); + final IncrementalStorage linkedApkStorage = + createStorage(targetStorageDir, apkStorage, + IncrementalManager.CREATE_MODE_CREATE + | IncrementalManager.CREATE_MODE_PERMANENT_BIND); if (linkedApkStorage == null) { - throw new IOException("Failed to create linked storage at dir: " + afterCodePathParent); + throw new IOException("Failed to create linked storage at dir: " + targetStorageDir); + } + try { + final String afterCodePathName = afterCodeFile.getName(); + linkFiles(apkStorage, beforeCodeAbsolute, "", linkedApkStorage, afterCodePathName); + apkStorage.unBind(beforeCodeAbsolute.toString()); + } catch (Exception e) { + linkedApkStorage.unBind(targetStorageDir); + throw e; } - linkFiles(apkStorage, beforeCodeFile, "", linkedApkStorage, afterCodePathName); - apkStorage.unBind(beforeCodePath); } /** @@ -252,22 +235,27 @@ public final class IncrementalManager { private void linkFiles(IncrementalStorage sourceStorage, File sourceAbsolutePath, String sourceRelativePath, IncrementalStorage targetStorage, String targetRelativePath) throws IOException { - targetStorage.makeDirectory(targetRelativePath); - final File[] entryList = sourceAbsolutePath.listFiles(); - for (int i = 0; i < entryList.length; i++) { - final File entry = entryList[i]; - final String entryName = entryList[i].getName(); - final String sourceEntryRelativePath = - sourceRelativePath.isEmpty() ? entryName : sourceRelativePath + "/" + entryName; - final String targetEntryRelativePath = targetRelativePath + "/" + entryName; - if (entry.isFile()) { + final Path sourceBase = sourceAbsolutePath.toPath().resolve(sourceRelativePath); + final Path targetRelative = Paths.get(targetRelativePath); + Files.walkFileTree(sourceAbsolutePath.toPath(), new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) + throws IOException { + final Path relativeDir = sourceBase.relativize(dir); + targetStorage.makeDirectory(targetRelative.resolve(relativeDir).toString()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException { + final Path relativeFile = sourceBase.relativize(file); sourceStorage.makeLink( - sourceEntryRelativePath, targetStorage, targetEntryRelativePath); - } else if (entry.isDirectory()) { - linkFiles(sourceStorage, entry, sourceEntryRelativePath, targetStorage, - targetEntryRelativePath); + file.toAbsolutePath().toString(), targetStorage, + targetRelative.resolve(relativeFile).toString()); + return FileVisitResult.CONTINUE; } - } + }); } /** diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index fe340c46e3c4..ac1998a04016 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -8607,6 +8607,16 @@ public final class Settings { public static final String CONTROLS_ENABLED = "controls_enabled"; /** + * Whether power menu content (cards, passes, controls) will be shown when device is locked. + * + * 0 indicates hide and 1 indicates show. A non existent value will be treated as hide. + * @hide + */ + @TestApi + public static final String POWER_MENU_LOCKED_SHOW_CONTENT = + "power_menu_locked_show_content"; + + /** * Specifies whether the web action API is enabled. * * @hide diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java index df4ead13d5cb..28639b3ea2f7 100644 --- a/core/java/android/text/TextUtils.java +++ b/core/java/android/text/TextUtils.java @@ -748,7 +748,7 @@ public class TextUtils { int parcelableFlags) { if (cs instanceof Spanned) { p.writeInt(0); - p.writeString(cs.toString()); + p.writeString8(cs.toString()); Spanned sp = (Spanned) cs; Object[] os = sp.getSpans(0, cs.length(), Object.class); @@ -785,9 +785,9 @@ public class TextUtils { } else { p.writeInt(1); if (cs != null) { - p.writeString(cs.toString()); + p.writeString8(cs.toString()); } else { - p.writeString(null); + p.writeString8(null); } } } @@ -807,7 +807,7 @@ public class TextUtils { public CharSequence createFromParcel(Parcel p) { int kind = p.readInt(); - String string = p.readString(); + String string = p.readString8(); if (string == null) { return null; } diff --git a/core/java/android/text/style/DynamicDrawableSpan.java b/core/java/android/text/style/DynamicDrawableSpan.java index f37e4238a1c6..d6d99f846e16 100644 --- a/core/java/android/text/style/DynamicDrawableSpan.java +++ b/core/java/android/text/style/DynamicDrawableSpan.java @@ -166,7 +166,7 @@ public abstract class DynamicDrawableSpan extends ReplacementSpan { if (mVerticalAlignment == ALIGN_BASELINE) { transY -= paint.getFontMetricsInt().descent; } else if (mVerticalAlignment == ALIGN_CENTER) { - transY = (bottom - top) / 2 - b.getBounds().height() / 2; + transY = top + (bottom - top) / 2 - b.getBounds().height() / 2; } canvas.translate(x, transY); diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java index a72383913420..2dcfd899adf4 100644 --- a/core/java/android/view/InsetsSourceConsumer.java +++ b/core/java/android/view/InsetsSourceConsumer.java @@ -69,6 +69,13 @@ public class InsetsSourceConsumer { private Rect mPendingFrame; private Rect mPendingVisibleFrame; + /** + * Indicates if we have the pending animation. When we have the control, we need to play the + * animation if the requested visibility is different from the current state. But if we haven't + * had a leash yet, we will set this flag, and play the animation once we get the leash. + */ + private boolean mIsAnimationPending; + public InsetsSourceConsumer(@InternalInsetsType int type, InsetsState state, Supplier<Transaction> transactionSupplier, InsetsController controller) { mType = type; @@ -107,13 +114,21 @@ public class InsetsSourceConsumer { } else { // We are gaining control, and need to run an animation since previous state // didn't match - if (isRequestedVisibleAwaitingControl() != mState.getSource(mType).isVisible()) { - if (isRequestedVisibleAwaitingControl()) { + final boolean requestedVisible = isRequestedVisibleAwaitingControl(); + final boolean needAnimation = requestedVisible != mState.getSource(mType).isVisible(); + if (control.getLeash() != null && (needAnimation || mIsAnimationPending)) { + if (requestedVisible) { showTypes[0] |= toPublicType(getType()); } else { hideTypes[0] |= toPublicType(getType()); } + mIsAnimationPending = false; } else { + if (needAnimation) { + // We need animation but we haven't had a leash yet. Set this flag that when we + // get the leash we can play the deferred animation. + mIsAnimationPending = true; + } // We are gaining control, but don't need to run an animation. // However make sure that the leash visibility is still up to date. if (applyLocalVisibilityOverride()) { @@ -274,7 +289,10 @@ public class InsetsSourceConsumer { * the moment. */ protected void setRequestedVisible(boolean requestedVisible) { - mRequestedVisible = requestedVisible; + if (mRequestedVisible != requestedVisible) { + mRequestedVisible = requestedVisible; + mIsAnimationPending = false; + } if (applyLocalVisibilityOverride()) { mController.notifyVisibilityChanged(); } diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index fba6a55ef6db..94591eafe72d 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -145,6 +145,7 @@ public final class WindowManagerGlobal { public static final int ADD_INVALID_DISPLAY = -9; public static final int ADD_INVALID_TYPE = -10; public static final int ADD_INVALID_USER = -11; + public static final int ADD_TOO_MANY_TOKENS = -12; @UnsupportedAppUsage private static WindowManagerGlobal sDefaultWindowManager; diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 4980b335646b..6646c3188fc7 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -3437,6 +3437,7 @@ public class AccessibilityNodeInfo implements Parcelable { * @hide */ @UnsupportedAppUsage + @TestApi public long getSourceNodeId() { return mSourceNodeId; } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 9f03d956f22c..16e87f8bca9a 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -5863,6 +5863,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te case KeyEvent.KEYCODE_DPAD_RIGHT: case KeyEvent.KEYCODE_DPAD_CENTER: case KeyEvent.KEYCODE_ENTER: + case KeyEvent.KEYCODE_NUMPAD_ENTER: okToSend = false; break; case KeyEvent.KEYCODE_BACK: diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 8d9ae58be290..00526d9f8a2c 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -821,6 +821,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe // was a click, the text view gets the selected item // from the drop down as its content case KeyEvent.KEYCODE_ENTER: + case KeyEvent.KEYCODE_NUMPAD_ENTER: case KeyEvent.KEYCODE_DPAD_CENTER: case KeyEvent.KEYCODE_TAB: if (event.hasNoModifiers()) { diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 8595fece4278..6425cf11ccb3 100644..100755 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -1005,6 +1005,7 @@ public class ListPopupWindow implements ShowableListMenu { case KeyEvent.KEYCODE_DPAD_CENTER: case KeyEvent.KEYCODE_DPAD_DOWN: case KeyEvent.KEYCODE_DPAD_UP: + case KeyEvent.KEYCODE_NUMPAD_ENTER: return true; } } else { diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index e9e0c1498034..baaf2a763487 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -1033,6 +1033,7 @@ public class NumberPicker extends LinearLayout { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_CENTER: case KeyEvent.KEYCODE_ENTER: + case KeyEvent.KEYCODE_NUMPAD_ENTER: removeAllCallbacks(); break; case KeyEvent.KEYCODE_DPAD_DOWN: diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 7f6c0d2077f1..7016c5cf0de6 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -1213,7 +1213,7 @@ public class RemoteViews implements Parcelable, Filter { BitmapReflectionAction(Parcel in) { viewId = in.readInt(); - methodName = in.readString(); + methodName = in.readString8(); bitmapId = in.readInt(); bitmap = mBitmapCache.getBitmapForId(bitmapId); } @@ -1221,7 +1221,7 @@ public class RemoteViews implements Parcelable, Filter { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(viewId); - dest.writeString(methodName); + dest.writeString8(methodName); dest.writeInt(bitmapId); } @@ -1282,7 +1282,7 @@ public class RemoteViews implements Parcelable, Filter { ReflectionAction(Parcel in) { this.viewId = in.readInt(); - this.methodName = in.readString(); + this.methodName = in.readString8(); this.type = in.readInt(); //noinspection ConstantIfStatement if (false) { @@ -1318,7 +1318,7 @@ public class RemoteViews implements Parcelable, Filter { this.value = (char)in.readInt(); break; case STRING: - this.value = in.readString(); + this.value = in.readString8(); break; case CHAR_SEQUENCE: this.value = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); @@ -1347,7 +1347,7 @@ public class RemoteViews implements Parcelable, Filter { public void writeToParcel(Parcel out, int flags) { out.writeInt(this.viewId); - out.writeString(this.methodName); + out.writeString8(this.methodName); out.writeInt(this.type); //noinspection ConstantIfStatement if (false) { @@ -1383,7 +1383,7 @@ public class RemoteViews implements Parcelable, Filter { out.writeInt((int)((Character)this.value).charValue()); break; case STRING: - out.writeString((String)this.value); + out.writeString8((String)this.value); break; case CHAR_SEQUENCE: TextUtils.writeToParcel((CharSequence)this.value, out, flags); diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java index 15959c221ffc..6ef570cdc784 100644..100755 --- a/core/java/android/widget/SearchView.java +++ b/core/java/android/widget/SearchView.java @@ -1076,7 +1076,8 @@ public class SearchView extends LinearLayout implements CollapsibleActionView { // The search key is handled by the dialog's onKeyDown(). if (!mSearchSrcTextView.isEmpty() && event.hasNoModifiers()) { if (event.getAction() == KeyEvent.ACTION_UP) { - if (keyCode == KeyEvent.KEYCODE_ENTER) { + if (keyCode == KeyEvent.KEYCODE_ENTER + || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER) { v.cancelLongPress(); // Launch as a regular search. diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java index 217693eed686..61c77bc2f90e 100644 --- a/core/java/android/widget/SimpleMonthView.java +++ b/core/java/android/widget/SimpleMonthView.java @@ -420,6 +420,7 @@ class SimpleMonthView extends View { break; case KeyEvent.KEYCODE_DPAD_CENTER: case KeyEvent.KEYCODE_ENTER: + case KeyEvent.KEYCODE_NUMPAD_ENTER: if (mHighlightedDay != -1) { onDayClicked(mHighlightedDay); return true; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index e933f18af979..ec07574f141f 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8359,6 +8359,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener switch (keyCode) { case KeyEvent.KEYCODE_ENTER: + case KeyEvent.KEYCODE_NUMPAD_ENTER: if (event.hasNoModifiers()) { // When mInputContentType is set, we know that we are // running in a "modern" cupcake environment, so don't need @@ -8586,6 +8587,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return super.onKeyUp(keyCode, event); case KeyEvent.KEYCODE_ENTER: + case KeyEvent.KEYCODE_NUMPAD_ENTER: if (event.hasNoModifiers()) { if (mEditor != null && mEditor.mInputContentType != null && mEditor.mInputContentType.onEditorActionListener != null diff --git a/core/java/android/window/DisplayAreaInfo.aidl b/core/java/android/window/DisplayAreaInfo.aidl new file mode 100644 index 000000000000..b7450172c55a --- /dev/null +++ b/core/java/android/window/DisplayAreaInfo.aidl @@ -0,0 +1,18 @@ +/** + * Copyright (c) 2020, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.window; + +parcelable DisplayAreaInfo; diff --git a/core/java/android/window/DisplayAreaInfo.java b/core/java/android/window/DisplayAreaInfo.java new file mode 100644 index 000000000000..0d35bcafdf45 --- /dev/null +++ b/core/java/android/window/DisplayAreaInfo.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.window; + +import android.annotation.NonNull; +import android.annotation.TestApi; +import android.content.res.Configuration; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Stores information about a particular {@link com.android.server.wm.DisplayArea}. This object will + * be sent to registered {@link DisplayAreaOrganizer} to provide information when the DisplayArea + * is added, removed, or changed. + * + * @hide + */ +@TestApi +public final class DisplayAreaInfo implements Parcelable { + + @NonNull + public final WindowContainerToken token; + + @NonNull + public final Configuration configuration = new Configuration(); + + /** + * The id of the display this display area is associated with. + */ + public final int displayId; + + public DisplayAreaInfo(@NonNull WindowContainerToken token, int displayId) { + this.token = token; + this.displayId = displayId; + } + + private DisplayAreaInfo(Parcel in) { + token = WindowContainerToken.CREATOR.createFromParcel(in); + configuration.readFromParcel(in); + displayId = in.readInt(); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + token.writeToParcel(dest, flags); + configuration.writeToParcel(dest, flags); + dest.writeInt(displayId); + } + + @NonNull + public static final Creator<DisplayAreaInfo> CREATOR = new Creator<DisplayAreaInfo>() { + @Override + public DisplayAreaInfo createFromParcel(Parcel in) { + return new DisplayAreaInfo(in); + } + + @Override + public DisplayAreaInfo[] newArray(int size) { + return new DisplayAreaInfo[size]; + } + }; + + @Override + public String toString() { + return "DisplayAreaInfo{token=" + token + + " config=" + configuration + "}"; + } + + @Override + public int describeContents() { + return 0; + } +} diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java index 6ae70b779960..f3ef5a0c0aa2 100644 --- a/core/java/android/window/DisplayAreaOrganizer.java +++ b/core/java/android/window/DisplayAreaOrganizer.java @@ -52,21 +52,42 @@ public class DisplayAreaOrganizer extends WindowOrganizer { } } - public void onDisplayAreaAppeared(@NonNull WindowContainerToken displayArea) {} + /** + * @hide + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + public void unregisterOrganizer() { + try { + getController().unregisterOrganizer(mInterface); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo) {} - public void onDisplayAreaVanished(@NonNull WindowContainerToken displayArea) {} + public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) {} + /** + * @hide + */ + public void onDisplayAreaInfoChanged(@NonNull DisplayAreaInfo displayAreaInfo) {} private final IDisplayAreaOrganizer mInterface = new IDisplayAreaOrganizer.Stub() { @Override - public void onDisplayAreaAppeared(@NonNull WindowContainerToken displayArea) { - DisplayAreaOrganizer.this.onDisplayAreaAppeared(displayArea); + public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo) { + DisplayAreaOrganizer.this.onDisplayAreaAppeared(displayAreaInfo); + } + + @Override + public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) { + DisplayAreaOrganizer.this.onDisplayAreaVanished(displayAreaInfo); } @Override - public void onDisplayAreaVanished(@NonNull WindowContainerToken displayArea) { - DisplayAreaOrganizer.this.onDisplayAreaVanished(displayArea); + public void onDisplayAreaInfoChanged(@NonNull DisplayAreaInfo displayAreaInfo) { + DisplayAreaOrganizer.this.onDisplayAreaInfoChanged(displayAreaInfo); } }; diff --git a/core/java/android/window/IDisplayAreaOrganizer.aidl b/core/java/android/window/IDisplayAreaOrganizer.aidl index 9c72e60c894c..39a9235a4224 100644 --- a/core/java/android/window/IDisplayAreaOrganizer.aidl +++ b/core/java/android/window/IDisplayAreaOrganizer.aidl @@ -16,13 +16,14 @@ package android.window; -import android.window.WindowContainerToken; +import android.window.DisplayAreaInfo; /** * Interface for WindowManager to delegate control of display areas. * {@hide} */ oneway interface IDisplayAreaOrganizer { - void onDisplayAreaAppeared(in WindowContainerToken displayArea); - void onDisplayAreaVanished(in WindowContainerToken displayArea); + void onDisplayAreaAppeared(in DisplayAreaInfo displayAreaInfo); + void onDisplayAreaVanished(in DisplayAreaInfo displayAreaInfo); + void onDisplayAreaInfoChanged(in DisplayAreaInfo displayAreaInfo); } diff --git a/core/java/android/window/IDisplayAreaOrganizerController.aidl b/core/java/android/window/IDisplayAreaOrganizerController.aidl index fc6fbef39ce2..41b9d027344e 100644 --- a/core/java/android/window/IDisplayAreaOrganizerController.aidl +++ b/core/java/android/window/IDisplayAreaOrganizerController.aidl @@ -23,4 +23,9 @@ interface IDisplayAreaOrganizerController { /** Register a DisplayAreaOrganizer to manage display areas for a given feature. */ void registerOrganizer(in IDisplayAreaOrganizer organizer, int displayAreaFeature); + + /** + * Unregisters a previously registered display area organizer. + */ + void unregisterOrganizer(in IDisplayAreaOrganizer organizer); } diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java index b1e356d258ee..bcb32fb60f47 100644 --- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java @@ -437,6 +437,9 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { resetViewVisibilitiesForWorkProfileEmptyState(emptyStateView); emptyStateView.setVisibility(View.VISIBLE); + View container = emptyStateView.findViewById(R.id.resolver_empty_state_container); + setupContainerPadding(container); + TextView title = emptyStateView.findViewById(R.id.resolver_empty_state_title); title.setText(titleRes); @@ -463,6 +466,12 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { activeListAdapter.markTabLoaded(); } + /** + * Sets up the padding of the view containing the empty state screens. + * <p>This method is meant to be overridden so that subclasses can customize the padding. + */ + protected void setupContainerPadding(View container) {} + private void showConsumerUserNoAppsAvailableEmptyState(ResolverListAdapter activeListAdapter) { ProfileDescriptor descriptor = getItem( userHandleToPageIndex(activeListAdapter.getUserHandle())); diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 970bab9bc53b..b671fa74bf9a 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -2721,11 +2721,12 @@ public class ChooserActivity extends ResolverActivity implements } private void setupScrollListener() { - if (mResolverDrawerLayout == null || shouldShowTabs()) { + if (mResolverDrawerLayout == null) { return; } - final View chooserHeader = mResolverDrawerLayout.findViewById(R.id.chooser_header); - final float defaultElevation = chooserHeader.getElevation(); + int elevatedViewResId = shouldShowTabs() ? R.id.resolver_tab_divider : R.id.chooser_header; + final View elevatedView = mResolverDrawerLayout.findViewById(elevatedViewResId); + final float defaultElevation = elevatedView.getElevation(); final float chooserHeaderScrollElevation = getResources().getDimensionPixelSize(R.dimen.chooser_header_scroll_elevation); @@ -2738,12 +2739,12 @@ public class ChooserActivity extends ResolverActivity implements if (view.getChildCount() > 0) { View child = view.getLayoutManager().findViewByPosition(0); if (child == null || child.getTop() < 0) { - chooserHeader.setElevation(chooserHeaderScrollElevation); + elevatedView.setElevation(chooserHeaderScrollElevation); return; } } - chooserHeader.setElevation(defaultElevation); + elevatedView.setElevation(defaultElevation); } }); } @@ -2885,6 +2886,13 @@ public class ChooserActivity extends ResolverActivity implements return METRICS_CATEGORY_CHOOSER; } + @Override + protected void onProfileTabSelected() { + ChooserGridAdapter currentRootAdapter = + mChooserMultiProfilePagerAdapter.getCurrentRootAdapter(); + currentRootAdapter.updateDirectShareExpansion(); + } + /** * Adapter for all types of items and targets in ShareSheet. * Note that ranked sections like Direct Share - while appearing grid-like - are handled on the @@ -3357,15 +3365,7 @@ public class ChooserActivity extends ResolverActivity implements } public void handleScroll(View v, int y, int oldy) { - // Only expand direct share area if there is a minimum number of shortcuts, - // which will help reduce the amount of visible shuffling due to older-style - // direct share targets. - int orientation = getResources().getConfiguration().orientation; - boolean canExpandDirectShare = - mChooserListAdapter.getNumShortcutResults() > getMaxTargetsPerRow() - && orientation == Configuration.ORIENTATION_PORTRAIT - && !isInMultiWindowMode(); - + boolean canExpandDirectShare = canExpandDirectShare(); if (mDirectShareViewHolder != null && canExpandDirectShare) { mDirectShareViewHolder.handleScroll( mChooserMultiProfilePagerAdapter.getActiveAdapterView(), y, oldy, @@ -3373,6 +3373,18 @@ public class ChooserActivity extends ResolverActivity implements } } + /** + * Only expand direct share area if there is a minimum number of shortcuts, + * which will help reduce the amount of visible shuffling due to older-style + * direct share targets. + */ + private boolean canExpandDirectShare() { + int orientation = getResources().getConfiguration().orientation; + return mChooserListAdapter.getNumShortcutResults() > getMaxTargetsPerRow() + && orientation == Configuration.ORIENTATION_PORTRAIT + && !isInMultiWindowMode(); + } + public ChooserListAdapter getListAdapter() { return mChooserListAdapter; } @@ -3380,6 +3392,19 @@ public class ChooserActivity extends ResolverActivity implements boolean shouldCellSpan(int position) { return getItemViewType(position) == VIEW_TYPE_NORMAL; } + + void updateDirectShareExpansion() { + if (mDirectShareViewHolder == null || !canExpandDirectShare()) { + return; + } + RecyclerView activeAdapterView = + mChooserMultiProfilePagerAdapter.getActiveAdapterView(); + if (mResolverDrawerLayout.isCollapsed()) { + mDirectShareViewHolder.collapse(activeAdapterView); + } else { + mDirectShareViewHolder.expand(activeAdapterView); + } + } } /** @@ -3577,6 +3602,20 @@ public class ChooserActivity extends ResolverActivity implements newHeight = Math.max(newHeight, mDirectShareMinHeight); yDiff = newHeight - prevHeight; + updateDirectShareRowHeight(view, yDiff, newHeight); + } + + void expand(RecyclerView view) { + updateDirectShareRowHeight(view, mDirectShareMaxHeight - mDirectShareCurrHeight, + mDirectShareMaxHeight); + } + + void collapse(RecyclerView view) { + updateDirectShareRowHeight(view, mDirectShareMinHeight - mDirectShareCurrHeight, + mDirectShareMinHeight); + } + + private void updateDirectShareRowHeight(RecyclerView view, int yDiff, int newHeight) { if (view == null || view.getChildCount() == 0 || yDiff == 0) { return; } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 1bc982cdb42b..00faa3b3d21e 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -146,6 +146,7 @@ public class ResolverActivity extends Activity implements private static final String TAG = "ResolverActivity"; private static final boolean DEBUG = false; + private static final String LAST_SHOWN_TAB_KEY = "last_shown_tab_key"; private boolean mRegistered; @@ -844,9 +845,19 @@ public class ResolverActivity extends Activity implements } @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + ViewPager viewPager = findViewById(R.id.profile_pager); + outState.putInt(LAST_SHOWN_TAB_KEY, viewPager.getCurrentItem()); + } + + @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); resetButtonBar(); + ViewPager viewPager = findViewById(R.id.profile_pager); + viewPager.setCurrentItem(savedInstanceState.getInt(LAST_SHOWN_TAB_KEY)); + mMultiProfilePagerAdapter.clearInactiveProfileCache(); } private boolean isHttpSchemeAndViewAction(Intent intent) { @@ -1585,6 +1596,7 @@ public class ResolverActivity extends Activity implements TabHost tabHost = findViewById(R.id.profile_tabhost); tabHost.setup(); ViewPager viewPager = findViewById(R.id.profile_pager); + viewPager.setSaveEnabled(false); TabHost.TabSpec tabSpec = tabHost.newTabSpec(TAB_TAG_PERSONAL) .setContent(R.id.profile_pager) .setIndicator(getString(R.string.resolver_personal_tab)); @@ -1610,6 +1622,7 @@ public class ResolverActivity extends Activity implements } setupViewVisibilities(); maybeLogProfileChange(); + onProfileTabSelected(); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.RESOLVER_SWITCH_TABS) .setInt(viewPager.getCurrentItem()) @@ -1628,6 +1641,12 @@ public class ResolverActivity extends Activity implements findViewById(R.id.resolver_tab_divider).setVisibility(View.VISIBLE); } + /** + * Callback called when user changes the profile tab. + * <p>This method is intended to be overridden by subclasses. + */ + protected void onProfileTabSelected() { } + private void resetCheckedItem() { if (!isIntentPicker()) { return; @@ -1745,22 +1764,33 @@ public class ResolverActivity extends Activity implements return; } final ViewGroup buttonLayout = findViewById(R.id.button_bar); - if (buttonLayout != null) { - buttonLayout.setVisibility(View.VISIBLE); - - if (!useLayoutWithDefault()) { - int inset = mSystemWindowInsets != null ? mSystemWindowInsets.bottom : 0; - buttonLayout.setPadding(buttonLayout.getPaddingLeft(), buttonLayout.getPaddingTop(), - buttonLayout.getPaddingRight(), getResources().getDimensionPixelSize( - R.dimen.resolver_button_bar_spacing) + inset); - } - mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once); - mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always); - - resetAlwaysOrOnceButtonBar(); - } else { + if (buttonLayout == null) { Log.e(TAG, "Layout unexpectedly does not have a button bar"); + return; + } + ResolverListAdapter activeListAdapter = + mMultiProfilePagerAdapter.getActiveListAdapter(); + View buttonBarDivider = findViewById(R.id.resolver_button_bar_divider); + if (activeListAdapter.isTabLoaded() + && mMultiProfilePagerAdapter.shouldShowEmptyStateScreen(activeListAdapter)) { + buttonLayout.setVisibility(View.INVISIBLE); + buttonBarDivider.setVisibility(View.INVISIBLE); + return; } + + buttonBarDivider.setVisibility(View.VISIBLE); + buttonLayout.setVisibility(View.VISIBLE); + + if (!useLayoutWithDefault()) { + int inset = mSystemWindowInsets != null ? mSystemWindowInsets.bottom : 0; + buttonLayout.setPadding(buttonLayout.getPaddingLeft(), buttonLayout.getPaddingTop(), + buttonLayout.getPaddingRight(), getResources().getDimensionPixelSize( + R.dimen.resolver_button_bar_spacing) + inset); + } + mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once); + mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always); + + resetAlwaysOrOnceButtonBar(); } private void resetAlwaysOrOnceButtonBar() { diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java index ad31d8b2e49a..885d1bbc5b77 100644 --- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java @@ -213,6 +213,12 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA /* subtitleRes */ 0); } + @Override + protected void setupContainerPadding(View container) { + container.setPadding(container.getPaddingLeft(), container.getPaddingTop(), + container.getPaddingRight(), /* bottom */ 0); + } + class ResolverProfileDescriptor extends ProfileDescriptor { private ResolverListAdapter resolverListAdapter; final ListView listView; diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 43bd4a610910..64324756796a 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -6093,7 +6093,8 @@ public class BatteryStatsImpl extends BatteryStats { return array; } - public void noteNetworkInterfaceTypeLocked(String iface, int networkType) { + /** @hide */ + public void noteNetworkInterfaceType(String iface, int networkType) { if (TextUtils.isEmpty(iface)) return; synchronized (mModemNetworkLock) { diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index 31527e8dbe5d..fb2ecf3a478f 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -1084,6 +1084,7 @@ public class ResolverDrawerLayout extends ViewGroup { protected Parcelable onSaveInstanceState() { final SavedState ss = new SavedState(super.onSaveInstanceState()); ss.open = mCollapsibleHeight > 0 && mCollapseOffset == 0; + ss.mCollapsibleHeightReserved = mCollapsibleHeightReserved; return ss; } @@ -1092,6 +1093,7 @@ public class ResolverDrawerLayout extends ViewGroup { final SavedState ss = (SavedState) state; super.onRestoreInstanceState(ss.getSuperState()); mOpenOnLayout = ss.open; + mCollapsibleHeightReserved = ss.mCollapsibleHeightReserved; } public static class LayoutParams extends MarginLayoutParams { @@ -1142,6 +1144,7 @@ public class ResolverDrawerLayout extends ViewGroup { static class SavedState extends BaseSavedState { boolean open; + private int mCollapsibleHeightReserved; SavedState(Parcelable superState) { super(superState); @@ -1150,12 +1153,14 @@ public class ResolverDrawerLayout extends ViewGroup { private SavedState(Parcel in) { super(in); open = in.readInt() != 0; + mCollapsibleHeightReserved = in.readInt(); } @Override public void writeToParcel(Parcel out, int flags) { super.writeToParcel(out, flags); out.writeInt(open ? 1 : 0); + out.writeInt(mCollapsibleHeightReserved); } public static final Parcelable.Creator<SavedState> CREATOR = diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index b51d4f509f38..4cb2e975a58b 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -301,6 +301,8 @@ AndroidRuntime::~AndroidRuntime() } void AndroidRuntime::setArgv0(const char* argv0, bool setProcName) { + // Set the kernel's task name, for as much of the name as we can fit. + // The kernel's TASK_COMM_LEN minus one for the terminating NUL == 15. if (setProcName) { int len = strlen(argv0); if (len < 15) { @@ -309,8 +311,14 @@ void AndroidRuntime::setArgv0(const char* argv0, bool setProcName) { pthread_setname_np(pthread_self(), argv0 + len - 15); } } + + // Directly change the memory pointed to by argv[0]. memset(mArgBlockStart, 0, mArgBlockLength); strlcpy(mArgBlockStart, argv0, mArgBlockLength); + + // Let bionic know that we just did that, because __progname points + // into argv[0] (https://issuetracker.google.com/152893281). + setprogname(mArgBlockStart); } status_t AndroidRuntime::callMain(const String8& className, jclass clazz, diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index 483b455965f7..e7a2fb428b50 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -273,7 +273,28 @@ static void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jlong nativ } } -static void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val) +static void android_os_Parcel_writeString8(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val) +{ + Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); + if (parcel != NULL) { + status_t err = NO_MEMORY; + if (val) { + const size_t len = env->GetStringUTFLength(val); + const char* str = env->GetStringUTFChars(val, 0); + if (str) { + err = parcel->writeString8(str, len); + env->ReleaseStringUTFChars(val, str); + } + } else { + err = parcel->writeString8(NULL, 0); + } + if (err != NO_ERROR) { + signalExceptionForError(env, clazz, err); + } + } +} + +static void android_os_Parcel_writeString16(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -444,7 +465,21 @@ static jdouble android_os_Parcel_readDouble(jlong nativePtr) return 0; } -static jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jlong nativePtr) +static jstring android_os_Parcel_readString8(JNIEnv* env, jclass clazz, jlong nativePtr) +{ + Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); + if (parcel != NULL) { + size_t len; + const char* str = parcel->readString8Inplace(&len); + if (str) { + return env->NewStringUTF(str); + } + return NULL; + } + return NULL; +} + +static jstring android_os_Parcel_readString16(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -722,7 +757,9 @@ static const JNINativeMethod gParcelMethods[] = { // @FastNative {"nativeWriteDouble", "(JD)V", (void*)android_os_Parcel_writeDouble}, // @FastNative - {"nativeWriteString", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString}, + {"nativeWriteString8", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString8}, + // @FastNative + {"nativeWriteString16", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString16}, // @FastNative {"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder}, // @FastNative @@ -740,7 +777,9 @@ static const JNINativeMethod gParcelMethods[] = { // @CriticalNative {"nativeReadDouble", "(J)D", (void*)android_os_Parcel_readDouble}, // @FastNative - {"nativeReadString", "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString}, + {"nativeReadString8", "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString8}, + // @FastNative + {"nativeReadString16", "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString16}, // @FastNative {"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}, // @FastNative diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 21985f0bb4bb..3a5720fd8c4c 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -1555,22 +1555,15 @@ static void isolateJitProfile(JNIEnv* env, jobjectArray pkg_data_info_list, static void BindMountStorageToLowerFs(const userid_t user_id, const char* dir_name, const char* package, fail_fn_t fail_fn) { - bool hasPackage = (package != nullptr); bool hasSdcardFs = IsFilesystemSupported("sdcardfs"); std::string source; if (hasSdcardFs) { - source = hasPackage ? - StringPrintf("/mnt/runtime/default/emulated/%d/%s/%s", user_id, dir_name, package) : - StringPrintf("/mnt/runtime/default/emulated/%d/%s", user_id, dir_name); + source = StringPrintf("/mnt/runtime/default/emulated/%d/%s/%s", user_id, dir_name, package); } else { - source = hasPackage ? - StringPrintf("/mnt/pass_through/%d/emulated/%d/%s/%s", - user_id, user_id, dir_name, package) : - StringPrintf("/mnt/pass_through/%d/emulated/%d/%s", user_id, user_id, dir_name); + source = StringPrintf("/mnt/pass_through/%d/emulated/%d/%s/%s", + user_id, user_id, dir_name, package); } - std::string target = hasPackage ? - StringPrintf("/storage/emulated/%d/%s/%s", user_id, dir_name, package) : - StringPrintf("/storage/emulated/%d/%s", user_id, dir_name); + std::string target = StringPrintf("/storage/emulated/%d/%s/%s", user_id, dir_name, package); if (access(source.c_str(), F_OK) != 0) { fail_fn(CREATE_ERROR("Error accessing %s: %s", source.c_str(), strerror(errno))); @@ -1594,10 +1587,7 @@ static void BindMountStorageDirs(JNIEnv* env, jobjectArray pkg_data_info_list, int size = (pkg_data_info_list != nullptr) ? env->GetArrayLength(pkg_data_info_list) : 0; if (size == 0) { - // App data isolation is not enabled for this process, so we bind mount to whole obb/ dir. - BindMountStorageToLowerFs(user_id, "Android/obb", /* package */ nullptr, fail_fn); - BindMountStorageToLowerFs(user_id, "Android/data", /* package */ nullptr, fail_fn); - return; + fail_fn(CREATE_ERROR("Data package list cannot be empty")); } // Bind mount each package obb directory diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto index 3e007e4704a4..997829eacf96 100644 --- a/core/proto/android/app/settings_enums.proto +++ b/core/proto/android/app/settings_enums.proto @@ -2523,16 +2523,10 @@ enum PageId { // OS: R PANEL_ADD_WIFI_NETWORKS = 1809; - // OPEN: Settings > Accessibility > Enable accessibility service > Show tutorial dialog + // OPEN: Settings > Accessibility > Enable the feature or shortcut > Show tutorial dialog // CATEGORY: SETTINGS // OS: R - DIALOG_TOGGLE_SCREEN_ACCESSIBILITY_BUTTON = 1810; - - // OPEN: Settings > Accessibility > Enable accessibility service > Show tutorial dialog in - // gesture mode - // CATEGORY: SETTINGS - // OS: R - DIALOG_TOGGLE_SCREEN_GESTURE_NAVIGATION = 1811; + DIALOG_ACCESSIBILITY_TUTORIAL = 1810; // OPEN: Settings > Accessibility > Edit shortcut dialog // CATEGORY: SETTINGS diff --git a/core/proto/android/app/tvsettings_enums.proto b/core/proto/android/app/tvsettings_enums.proto index 6804d3f07736..30d365c71308 100644 --- a/core/proto/android/app/tvsettings_enums.proto +++ b/core/proto/android/app/tvsettings_enums.proto @@ -298,6 +298,12 @@ enum ItemId { // TvSettings > Apps > See all apps > [An app entry] > Permissions APPS_ALL_APPS_APP_ENTRY_PERMISSIONS = 0x1611A000; + // TvSettings > Apps > See all apps > [An app entry] > Enable + APPS_ALL_APPS_APP_ENTRY_ENABLE = 0x1611B000; + + // TvSettings > Apps > See all apps > [An app entry] > Open source licenses + APPS_ALL_APPS_APP_ENTRY_LICENSES = 0x1611C000; + // TvSettings > Apps > See all apps > Show system apps APPS_ALL_APPS_SHOW_SYSTEM_APPS = 0x16120000; diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto index 075aa97edb58..fe8a0f183546 100644 --- a/core/proto/android/providers/settings/secure.proto +++ b/core/proto/android/providers/settings/secure.proto @@ -397,6 +397,13 @@ message SecureSettingsProto { } optional ParentalControl parental_control = 43; + message PowerMenuPrivacy { + option (android.msg_privacy).dest = DEST_EXPLICIT; + + optional SettingProto show = 1 [ (android.privacy).dest = DEST_AUTOMATIC ]; + } + optional PowerMenuPrivacy power_menu_privacy = 81; + message PrintService { option (android.msg_privacy).dest = DEST_EXPLICIT; @@ -588,5 +595,5 @@ message SecureSettingsProto { // Please insert fields in alphabetical order and group them into messages // if possible (to avoid reaching the method limit). - // Next tag = 80; + // Next tag = 82; } diff --git a/core/proto/android/stats/accessibility/accessibility_enums.proto b/core/proto/android/stats/accessibility/accessibility_enums.proto new file mode 100644 index 000000000000..5118ad5a322c --- /dev/null +++ b/core/proto/android/stats/accessibility/accessibility_enums.proto @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; +package android.stats.accessibility; +option java_multiple_files = true; + +// The entry point of the accessibility shortcut. +enum ShortcutType { + UNKNOWN_TYPE = 0; + A11Y_BUTTON = 1; + VOLUME_KEY = 2; + TRIPLE_TAP = 3; + A11Y_BUTTON_LONG_PRESS = 4; +} + +// The service status code. +enum ServiceStatus { + UNKNOWN = 0; + ENABLED = 1; + DISABLED = 2; +}
\ No newline at end of file diff --git a/core/proto/android/stats/dnsresolver/dns_resolver.proto b/core/proto/android/stats/dnsresolver/dns_resolver.proto index 61b9b25fe7cf..b17d12c9c315 100644 --- a/core/proto/android/stats/dnsresolver/dns_resolver.proto +++ b/core/proto/android/stats/dnsresolver/dns_resolver.proto @@ -211,7 +211,7 @@ enum CacheStatus{ // 1. bionic/libc/kernel/uapi/asm-generic/errno-base.h // 2. bionic/libc/kernel/uapi/asm-generic/errno.h enum LinuxErrno { - SYS_UNKNOWN = 0; + SYS_NO_ERROR = 0; SYS_EPERM = 1; // Not super-user SYS_ENOENT = 2; // No such file or directory SYS_ESRCH = 3; // No such process diff --git a/core/res/res/drawable-hdpi/ic_user_secure.png b/core/res/res/drawable-hdpi/ic_user_secure.png Binary files differdeleted file mode 100644 index 60dcf2adc786..000000000000 --- a/core/res/res/drawable-hdpi/ic_user_secure.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_user_secure.png b/core/res/res/drawable-mdpi/ic_user_secure.png Binary files differdeleted file mode 100644 index 0dea77a7b8b8..000000000000 --- a/core/res/res/drawable-mdpi/ic_user_secure.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_user_secure.png b/core/res/res/drawable-xhdpi/ic_user_secure.png Binary files differdeleted file mode 100644 index a6ef51af2ea8..000000000000 --- a/core/res/res/drawable-xhdpi/ic_user_secure.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/ic_user_secure.png b/core/res/res/drawable-xxhdpi/ic_user_secure.png Binary files differdeleted file mode 100644 index e6154e59518d..000000000000 --- a/core/res/res/drawable-xxhdpi/ic_user_secure.png +++ /dev/null diff --git a/core/res/res/drawable-xxxhdpi/ic_user_secure.png b/core/res/res/drawable-xxxhdpi/ic_user_secure.png Binary files differdeleted file mode 100644 index 9a3959b292a3..000000000000 --- a/core/res/res/drawable-xxxhdpi/ic_user_secure.png +++ /dev/null diff --git a/packages/Tethering/res/values-mcc312-mnc530/strings.xml b/core/res/res/drawable/ic_user_secure.xml index 618df90c7105..9e6355cdc481 100644 --- a/packages/Tethering/res/values-mcc312-mnc530/strings.xml +++ b/core/res/res/drawable/ic_user_secure.xml @@ -13,10 +13,12 @@ See the License for the specific language governing permissions and limitations under the License. --> -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- String for tethered notification title with client number info. --> - <plurals name="tethered_notification_title_with_client_number"> - <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item> - <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item> - </plurals> -</resources>
\ No newline at end of file +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM9,6c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v2L9,8L9,6zM18,20L6,20L6,10h12v10zM12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2z"/> +</vector> diff --git a/core/res/res/layout/resolver_empty_states.xml b/core/res/res/layout/resolver_empty_states.xml index 25615d2dc304..fe11769e8613 100644 --- a/core/res/res/layout/resolver_empty_states.xml +++ b/core/res/res/layout/resolver_empty_states.xml @@ -24,6 +24,7 @@ android:paddingStart="24dp" android:paddingEnd="24dp"> <RelativeLayout + android:id="@+id/resolver_empty_state_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="48dp" diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml index b754e0cfc022..76ecefc67c22 100644 --- a/core/res/res/layout/resolver_list.xml +++ b/core/res/res/layout/resolver_list.xml @@ -112,59 +112,61 @@ </FrameLayout> </LinearLayout> </TabHost> - - <View - android:layout_alwaysShow="true" - android:layout_width="match_parent" - android:layout_height="1dp" - android:background="?attr/colorBackgroundFloating" - android:foreground="?attr/dividerVertical" /> - <LinearLayout - android:id="@+id/button_bar" - android:visibility="gone" - style="?attr/buttonBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_ignoreOffset="true" android:layout_alwaysShow="true" - android:layout_hasNestedScrollIndicator="true" - android:gravity="end|center_vertical" - android:orientation="horizontal" - android:layoutDirection="locale" - android:measureWithLargestChild="true" - android:background="?attr/colorBackgroundFloating" - android:paddingTop="@dimen/resolver_button_bar_spacing" - android:paddingBottom="@dimen/resolver_button_bar_spacing" - android:paddingStart="@dimen/resolver_edge_margin" - android:paddingEnd="@dimen/resolver_small_margin" - android:elevation="@dimen/resolver_elevation"> - - <Button - android:id="@+id/button_once" - android:layout_width="wrap_content" - android:layout_gravity="start" - android:maxLines="2" - style="?attr/buttonBarButtonStyle" - android:fontFamily="@android:string/config_headlineFontFamilyMedium" + android:orientation="vertical" + android:background="?attr/colorBackgroundFloating"> + <View + android:id="@+id/resolver_button_bar_divider" + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?attr/colorBackgroundFloating" + android:foreground="?attr/dividerVertical" /> + <LinearLayout + android:id="@+id/button_bar" + android:visibility="gone" + style="?attr/buttonBarStyle" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAllCaps="false" - android:enabled="false" - android:text="@string/activity_resolver_use_once" - android:onClick="onButtonClick" /> + android:layout_ignoreOffset="true" + android:layout_hasNestedScrollIndicator="true" + android:gravity="end|center_vertical" + android:orientation="horizontal" + android:layoutDirection="locale" + android:measureWithLargestChild="true" + android:paddingTop="@dimen/resolver_button_bar_spacing" + android:paddingBottom="@dimen/resolver_button_bar_spacing" + android:paddingStart="@dimen/resolver_edge_margin" + android:paddingEnd="@dimen/resolver_small_margin" + android:elevation="@dimen/resolver_elevation"> - <Button - android:id="@+id/button_always" - android:layout_width="wrap_content" - android:layout_gravity="end" - android:maxLines="2" - style="?attr/buttonBarButtonStyle" - android:fontFamily="@android:string/config_headlineFontFamilyMedium" - android:textAllCaps="false" - android:layout_height="wrap_content" - android:enabled="false" - android:text="@string/activity_resolver_use_always" - android:onClick="onButtonClick" /> - </LinearLayout> + <Button + android:id="@+id/button_once" + android:layout_width="wrap_content" + android:layout_gravity="start" + android:maxLines="2" + style="?attr/buttonBarButtonStyle" + android:fontFamily="@android:string/config_headlineFontFamilyMedium" + android:layout_height="wrap_content" + android:textAllCaps="false" + android:enabled="false" + android:text="@string/activity_resolver_use_once" + android:onClick="onButtonClick" /> + <Button + android:id="@+id/button_always" + android:layout_width="wrap_content" + android:layout_gravity="end" + android:maxLines="2" + style="?attr/buttonBarButtonStyle" + android:fontFamily="@android:string/config_headlineFontFamilyMedium" + android:textAllCaps="false" + android:layout_height="wrap_content" + android:enabled="false" + android:text="@string/activity_resolver_use_always" + android:onClick="onButtonClick" /> + </LinearLayout> + </LinearLayout> </com.android.internal.widget.ResolverDrawerLayout> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index d8ab37f65dd0..9d152aaaa582 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Versoek deur <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ja"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nee"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"By noodligging ingegaan"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Jou toestelvervaardiger het tydens \'n onlangse noodsessie toegang tot jou ligging gekry"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Jou diensverskaffer het tydens \'n onlangse noodsessie toegang tot jou ligging gekry"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Uitveeperk is oorskry"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Daar is <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> uitgeveede items vir <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, rekening <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Wat wil jy doen?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Vee die items uit"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index eb18af6ad6eb..af6e15f57a70 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">" በ፡<xliff:g id="NAME">%1$s</xliff:g>(<xliff:g id="SERVICE">%2$s</xliff:g>) ተጠየቀ"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"አዎ"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"አይ"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"የድንገተኛ ጊዜ አካባቢ ተደርሶበታል"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"የእርስዎ መሣሪያ አምራች በቅርቡ በነበረ የድንገተኛ አደጋ ክፍለ-ጊዜ ላይ አካባቢዎን ደርሷል"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"የእርስዎ አገልግሎት አቅራቢ በቅርቡ በነበረ የድንገተኛ አደጋ ክፍለ-ጊዜ ላይ አካባቢዎን ደርሷል"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"የሰርዝ ወሰን ከመጠን አልፏል"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> የተሰረዙ ንጥሎች ለ<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>፣ <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> መለያ አሉ። ምን ማድረግ ትፈልጋለህ?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"ንጥሎቹን ሰርዝ"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 77692cf78b38..7a2639d1ccda 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -815,9 +815,9 @@ <string name="relationTypeFriend" msgid="3192092625893980574">"صديق"</string> <string name="relationTypeManager" msgid="2272860813153171857">"مدير"</string> <string name="relationTypeMother" msgid="2331762740982699460">"أم"</string> - <string name="relationTypeParent" msgid="4177920938333039882">"الوالدان"</string> + <string name="relationTypeParent" msgid="4177920938333039882">"ولي أمر"</string> <string name="relationTypePartner" msgid="4018017075116766194">"شريك"</string> - <string name="relationTypeReferredBy" msgid="5285082289602849400">"جهة الإحالة"</string> + <string name="relationTypeReferredBy" msgid="5285082289602849400">"جهة إحالة"</string> <string name="relationTypeRelative" msgid="3396498519818009134">"قريب"</string> <string name="relationTypeSister" msgid="3721676005094140671">"أخت"</string> <string name="relationTypeSpouse" msgid="6916682664436031703">"زوج/زوجة"</string> @@ -1541,12 +1541,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"مطلوب من <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"نعم"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"لا"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"تم الوصول إلى الموقع الجغرافي أثناء حالة طوارئ"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"وصلت الشركة المصنِّعة إلى موقعك الجغرافي أثناء جلسة الطوارئ الأخيرة."</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"وصل مشغّل شبكة الجوّال إلى موقعك الجغرافي أثناء جلسة الطوارئ الأخيرة."</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"تم تجاوز حد الحذف."</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"هناك <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> من العناصر المحذوفة لـ <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، في حساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. ماذا تريد أن تفعل؟"</string> <string name="sync_really_delete" msgid="5657871730315579051">"حذف العناصر"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 3fa7a7fbde52..c998ff026881 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) tərəfindən tələb edilib"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Bəli"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Xeyr"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Fövqəladə sessiyada məkana giriş edilib"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Son fövqəladə sessiya zamanı cihaz istehsalçısı məkanınıza giriş edib"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Son fövqəladə sessiya zamanı operator məkanınıza giriş edib"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Limiti keçəni silin"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> üçün <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> silinmiş fayl var, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> hesabı. Nə etmək istəyirsiniz?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Elementləri sil"</string> @@ -1907,7 +1904,7 @@ <string name="pin_specific_target" msgid="7824671240625957415">"İşarələyin: <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="unpin_target" msgid="3963318576590204447">"Çıxarın"</string> <string name="unpin_specific_target" msgid="3859828252160908146">"İşarələməyin: <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="app_info" msgid="6113278084877079851">"Tətbiq məlumatı"</string> + <string name="app_info" msgid="6113278084877079851">"Tətbiq infosu"</string> <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="6577581216125805905">"Demo başlayır…"</string> <string name="demo_restarting_message" msgid="1160053183701746766">"Cihaz sıfırlanır…"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 9f9d29318757..1bb162d6f3e3 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -1478,12 +1478,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Zahteva <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Da"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Ne"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Pristupljeno lokaciji za hitne slučajeve"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Proizvođač uređaja je pristupio vašoj lokaciji tokom nedavne hitne sesije"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Mobilni operater je pristupio vašoj lokaciji tokom nedavne hitne sesije"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Premašeno je ograničenje za brisanje"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Postoje izbrisane stavke (<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>) za <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, nalog <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Šta želite da uradite?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Izbriši stavke"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 6ab96fd85ea7..eb2f01bc6be1 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -1499,12 +1499,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Запыт ад карыстальнiка <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Так"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Не"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Атрыманы экстранны доступ да геаданых"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Вытворца вашай прылады атрымаў доступ да даных пра ваша месцазнаходжанне падчас нядаўняга сеанса экстраннага абагульвання"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Ваш аператар атрымаў доступ да даных пра ваша месцазнаходжанне падчас нядаўняга сеанса экстраннага абагульвання"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Выдаліць перавышаны ліміт"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Выдалена элементаў для тыпу сінхранiзацыi \"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>\": <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Уліковы запіс <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Што вы жадаеце зрабіць?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Выдаліць элементы."</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 3fc07e967e31..9e73d422eb6f 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Заявено от <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Да"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Не"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Осъщ. е достъп до местоп. при спешен случай"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Производителят на устройството ви осъществи достъп до местоположението ви по време на скорошна сесия за спешен случай"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Операторът ви осъществи достъп до местоположението ви по време на скорошна сесия за спешен случай"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Лимитът за изтриване бе надхвърлен"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Има <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> изтрити елемента за <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, профил <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Какво искате да направите?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Изтриване на елементите"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 937f8990252d..ee6bdd9a8ba3 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -1480,12 +1480,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Zahtjev uputio <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Da"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Ne"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Pristup lokaciji zbog hitnog slučaja"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Proizvođač uređaja je pristupio vašoj lokaciji za vrijeme nedavnog hitnog slučaja"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Mobilni operater je pristupio vašoj lokaciji za vrijeme nedavnog hitnog slučaja"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Granica za brisanje prekoračena"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Izbrisano je <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> stavki za <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, račun <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Šta želite uraditi?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Izbriši stavke"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index d8960b8aede4..ed77cddad8fa 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Sol·licitat per <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Sí"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"No"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"S\'ha accedit a la ubicació per emergència"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"El fabricant del teu dispositiu ha accedit a la teva ubicació durant una sessió d\'emergència recent"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"El teu operador ha accedit a la teva ubicació durant una sessió d\'emergència recent"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"S\'ha superat el límit de supressions"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Hi ha <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elements suprimits per a <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, compte <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Què vols fer?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Suprimeix els elements"</string> @@ -1834,7 +1831,7 @@ </plurals> <string name="zen_mode_until" msgid="2250286190237669079">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_alarm" msgid="7046911727540499275">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (propera alarma)"</string> - <string name="zen_mode_forever" msgid="740585666364912448">"Fins que no ho desactivi"</string> + <string name="zen_mode_forever" msgid="740585666364912448">"Fins que no el desactivis"</string> <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Fins que desactivis el mode No molestis"</string> <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="8009920446193610996">"Replega"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 9fee46f852a2..7149a8304fc7 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1499,12 +1499,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Požadavek od uživatele <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ano"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Ne"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Byl využit údaj o poloze v nouzi"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Výrobce vašeho zařízení při nedávném tísňovém volání získal přístup k vaší poloze"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Váš operátor při nedávném tísňovém volání získal přístup k vaší poloze"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Byl překročen limit mazání."</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Počet smazaných položek pro <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> (účet <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>): <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Co chcete dělat?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Smazat položky."</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index fe4861a70144..2c135fbdf124 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Anmodet om af <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ja"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nej"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Din placering i nødstilfælde er tilgået"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Din enheds producent fik adgang til din placering i løbet af en nødsituation for nylig"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Dit mobilselskab fik adgang til din placering i løbet af en nødsituation for nylig"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Grænsen for sletning er overskredet"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Der er <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> slettede emner for <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, konto <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Hvad vil du gøre?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Slet elementerne"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 02a047c681f6..95d71f61d0c3 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1015,8 +1015,8 @@ <string name="years" msgid="5797714729103773425">"Jahre"</string> <string name="now_string_shortest" msgid="3684914126941650330">"Jetzt"</string> <plurals name="duration_minutes_shortest" formatted="false" msgid="7519574894537185135"> - <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> min</item> - <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> min</item> + <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> Min.</item> + <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> Min.</item> </plurals> <plurals name="duration_hours_shortest" formatted="false" msgid="2838655994500499651"> <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item> @@ -1031,8 +1031,8 @@ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> J.</item> </plurals> <plurals name="duration_minutes_shortest_future" formatted="false" msgid="849196137176399440"> - <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> min</item> - <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> min</item> + <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> Min.</item> + <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> Min.</item> </plurals> <plurals name="duration_hours_shortest_future" formatted="false" msgid="5386373597343170388"> <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> h</item> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Angefordert von <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"\"Ja\""</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nein"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Zugriff auf Gerätestandort bei Notfall"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Dein Gerätehersteller hat vor Kurzem während eines Notfalls auf deinen Standort zugegriffen"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Dein Mobilfunkanbieter hat vor Kurzem während eines Notfalls auf deinen Standort zugegriffen"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Löschbegrenzung überschritten"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Es sind <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> gelöschte Elemente für <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, Konto <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>, vorhanden. Wie möchtest du fortfahren?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Elemente löschen"</string> @@ -1805,8 +1802,8 @@ <item quantity="one">1 Minute (bis <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item> </plurals> <plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="4230730310318858312"> - <item quantity="other">Für %1$d min (bis <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> - <item quantity="one">Für 1 min (bis <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item> + <item quantity="other">Für %1$d Min. (bis <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="one">Für 1 Min. (bis <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item> </plurals> <plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="7725354244196466758"> <item quantity="other">%1$d Stunden (bis <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> @@ -1821,8 +1818,8 @@ <item quantity="one">Für 1 Minute</item> </plurals> <plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2742377799995454859"> - <item quantity="other">Für %d min</item> - <item quantity="one">Für 1 min</item> + <item quantity="other">Für %d Min.</item> + <item quantity="one">Für 1 Min.</item> </plurals> <plurals name="zen_mode_duration_hours" formatted="false" msgid="525401855645490022"> <item quantity="other">%d Stunden</item> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 9687e6c48692..05b5e5281f7d 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Ζητήθηκε από <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ναι"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Όχι"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Πρόσβαση στην τοποθεσία έκτακτης ανάγκης"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Ο κατασκευαστής της συσκευής σας απέκτησε πρόσβαση στην τοποθεσία σας κατά τη διάρκεια μιας πρόσφατης περιόδου λειτουργίας έκτακτης ανάγκης."</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Η εταιρεία κινητής τηλεφωνίας σας απέκτησε πρόσβαση στην τοποθεσία σας κατά τη διάρκεια μιας πρόσφατης περιόδου λειτουργίας έκτακτης ανάγκης."</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Έγινε υπέρβαση του ορίου διαγραφής"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Υπάρχουν <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> διαγραμμένα στοιχεία για τον συγχρονισμό <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, στον λογαριασμό <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Τι θέλετε να κάνετε;"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Διαγραφή των στοιχείων"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 3bde4cb3f3b3..6c19031894a7 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Sí"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"No"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Se accedió a la ubicación en emergencia"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"El fabricante del dispositivo accedió a tu ubicación durante una sesión de emergencia reciente"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"El proveedor accedió a tu ubicación durante una sesión de emergencia reciente"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Eliminar el límite excedido"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Hay <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elementos eliminados para <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> en la cuenta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. ¿Qué quieres hacer?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Eliminar elementos"</string> @@ -2032,7 +2029,7 @@ <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> y <xliff:g id="COUNT_3">%d</xliff:g> archivos más</item> <item quantity="one"><xliff:g id="FILE_NAME_0">%s</xliff:g> y <xliff:g id="COUNT_1">%d</xliff:g> archivo más</item> </plurals> - <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"No hay personas recomendadas con las que compartir"</string> + <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"No hay personas recomendadas con quienes compartir"</string> <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista de apps"</string> <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Aunque no se le otorgó permiso de grabación a esta app, puede capturar audio con este dispositivo USB."</string> <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Página principal"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 87b0f799443e..b923564be9b9 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -192,7 +192,7 @@ <string name="network_logging_notification_title" msgid="554983187553845004">"El dispositivo está administrado"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Tu organización administra este dispositivo y puede supervisar el tráfico de red. Toca la notificación para obtener más información."</string> <string name="location_changed_notification_title" msgid="3620158742816699316">"Las aplicaciones pueden acceder a tu ubicación"</string> - <string name="location_changed_notification_text" msgid="7158423339982706912">"Para obtener más información, ponte en contacto con tu administrador de TI"</string> + <string name="location_changed_notification_text" msgid="7158423339982706912">"Contacta con tu admin. de TI para más información"</string> <string name="country_detector" msgid="7023275114706088854">"Detector de país"</string> <string name="location_service" msgid="2439187616018455546">"Servicio de ubicación"</string> <string name="sensor_notification_service" msgid="7474531979178682676">"Servicio de notificación de sensor"</string> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Solicitud enviada por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Sí"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"No"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Ubicación consultada durante emergencia"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"El fabricante de tu dispositivo ha consultado tu ubicación durante una sesión de emergencia reciente"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Tu operador ha consultado tu ubicación durante una sesión de emergencia reciente"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Se ha superado el límite de eliminaciones."</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Hay <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elementos eliminados para <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> (cuenta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>). ¿Qué quieres hacer?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Eliminar elementos"</string> @@ -2001,7 +1998,7 @@ <string name="notification_appops_microphone_active" msgid="581333393214739332">"Micrófono"</string> <string name="notification_appops_overlay_active" msgid="5571732753262836481">"se muestra sobre otras aplicaciones que haya en la pantalla"</string> <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación sobre el modo rutina"</string> - <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Es posible que te quedes sin batería antes de lo habitual"</string> + <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Puede que se agote la batería antes de lo habitual"</string> <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Se ha activado el modo Ahorro de batería para aumentar la duración de la batería"</string> <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ahorro de batería"</string> <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Ahorro de batería desactivado"</string> @@ -2032,7 +2029,7 @@ <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> y <xliff:g id="COUNT_3">%d</xliff:g> archivos</item> <item quantity="one"><xliff:g id="FILE_NAME_0">%s</xliff:g> y <xliff:g id="COUNT_1">%d</xliff:g> archivo</item> </plurals> - <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"No hay personas recomendadas con las que compartir"</string> + <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"No hay sugerencias de personas con las que compartir"</string> <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista de aplicaciones"</string> <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Esta aplicación no tiene permiso para grabar, pero podría registrar audio con este dispositivo USB."</string> <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Inicio"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 3de520e4dbec..518aa60d2bb1 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Taotleja: <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Jah"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Ei"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Hädaolukorra asukohale pääseti juurde"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Teie seadme tootja pääses hiljutise hädaolukorra seansi ajal teie asukohale juurde"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Teie operaator pääses hiljutise hädaolukorra seansi ajal teie asukohale juurde"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Kustutamiste piirarv on ületatud"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Kustutatavad üksused kontol <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> sünkroonimistüübi <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> jaoks: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Mida soovite teha?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Kustuta üksused"</string> @@ -1652,7 +1649,7 @@ <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Lülita otsetee välja"</string> <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kasuta otseteed"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Värvide ümberpööramine"</string> - <string name="color_correction_feature_name" msgid="3655077237805422597">"Värviparandus"</string> + <string name="color_correction_feature_name" msgid="3655077237805422597">"Värvide korrigeerimine"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse nuppe hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse nuppe hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kasutamiseks hoidke kolm sekundit all mõlemat helitugevuse klahvi"</string> @@ -1907,7 +1904,7 @@ <string name="pin_specific_target" msgid="7824671240625957415">"PIN-kood <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="unpin_target" msgid="3963318576590204447">"Vabasta"</string> <string name="unpin_specific_target" msgid="3859828252160908146">"Vabasta <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="app_info" msgid="6113278084877079851">"Rakenduse teave"</string> + <string name="app_info" msgid="6113278084877079851">"Rakenduste teave"</string> <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="6577581216125805905">"Demo käivitamine …"</string> <string name="demo_restarting_message" msgid="1160053183701746766">"Seadme lähtestamine …"</string> @@ -1986,7 +1983,7 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"AVA IKKA"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Tuvastati kahjulik rakendus"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Rakendus <xliff:g id="APP_0">%1$s</xliff:g> soovib näidata rakenduse <xliff:g id="APP_2">%2$s</xliff:g> lõike"</string> - <string name="screenshot_edit" msgid="7408934887203689207">"Muutmine"</string> + <string name="screenshot_edit" msgid="7408934887203689207">"Muuda"</string> <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Kõnede ja märguannete puhul seade vibreerib"</string> <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Kõned ja märguanded on vaigistatud"</string> <string name="notification_channel_system_changes" msgid="2462010596920209678">"Süsteemi muudatused"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 34117aa0fd48..f004b8adb371 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak eskatuta (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Bai"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Ez"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Larrialdiko kokapena atzitu da"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Gailuaren fabrikatzaileak zure kokapena atzitu zuen duela gutxi izandako larrialdiko saio baten harira"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Operadoreak zure kokapena atzitu zuen duela gutxi izandako larrialdiko saio baten harira"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Ezabatze-muga gainditu da"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Ezabatutako <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elementu daude <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> sinkronizazioan, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> kontuan. Zer egin nahi duzu?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Ezabatu elementuak"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 5b56437d726f..474c80306bef 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"درخواستکننده <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"بله"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"نه"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"از دسترسی به مکان اضطراری استفاده شد"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"سازنده دستگاهتان درحین یکی از جلسههای اضطراری اخیر به مکانتان دسترسی پیدا کرد"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"شرکت مخابراتیتان درحین یکی از جلسههای اضطراری اخیر به مکانتان دسترسی پیدا کرد"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"از حد مجاز حذف فراتر رفت"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> مورد حذفشده برای <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، حساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> وجود دارد. میخواهید چه کار بکنید؟"</string> <string name="sync_really_delete" msgid="5657871730315579051">"حذف موارد"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 77c0f0c866f0..24693271aaa4 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -191,7 +191,7 @@ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Järjestelmänvalvoja luovutti laitteen henkilökohtaiseen käyttöön"</string> <string name="network_logging_notification_title" msgid="554983187553845004">"Hallinnoitu laite"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Organisaatiosi hallinnoi tätä laitetta ja voi tarkkailla verkkoliikennettä. Katso lisätietoja napauttamalla."</string> - <string name="location_changed_notification_title" msgid="3620158742816699316">"Sovellukset voivat käyttää sijaintiasi"</string> + <string name="location_changed_notification_title" msgid="3620158742816699316">"Sovelluksilla on pääsy sijaintiisi"</string> <string name="location_changed_notification_text" msgid="7158423339982706912">"Saat lisätietoja järjestelmänvalvojalta."</string> <string name="country_detector" msgid="7023275114706088854">"Maan tunnistin"</string> <string name="location_service" msgid="2439187616018455546">"Sijaintipalvelu"</string> @@ -1307,7 +1307,7 @@ <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Analoginen äänilaite havaittu"</string> <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Liitetty laite ei ole yhteensopiva puhelimen kanssa. Napauta, niin näet lisätietoja."</string> <string name="adb_active_notification_title" msgid="408390247354560331">"USB-vianetsintä yhdistetty"</string> - <string name="adb_active_notification_message" msgid="5617264033476778211">"Poista USB-virheenkorjaus käytöstä napauttamalla"</string> + <string name="adb_active_notification_message" msgid="5617264033476778211">"Laita USB-vianetsintä pois päältä napauttamalla"</string> <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Poista USB-vianetsintä käytöstä valitsemalla tämä."</string> <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Langaton virheenkorjaus yhdistetty"</string> <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Poista langaton virheenkorjaus käytöstä napauttamalla"</string> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Pyytänyt <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Kyllä"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Ei"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Hätätilanteen sijainti nähty"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Laitteesi valmistaja näki sijaintisi viimeaikaisen hätätilanteen aikana"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Operaattori näki sijaintisi viimeaikaisen hätätilanteen aikana"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Poistoraja ylittynyt"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Tilin <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> synkronointityypissä <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> on <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> poistettua kohdetta. Mitä tehdään?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Poista kohteet"</string> @@ -1834,7 +1831,7 @@ </plurals> <string name="zen_mode_until" msgid="2250286190237669079">"Kunnes kello on <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> asti (seuraava hälytys)"</string> - <string name="zen_mode_forever" msgid="740585666364912448">"Kunnes poistat sen käytöstä"</string> + <string name="zen_mode_forever" msgid="740585666364912448">"Kunnes laitat pois päältä"</string> <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Kunnes poistat Varattu-tilan käytöstä."</string> <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="8009920446193610996">"Kutista"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 2b3b555c0cdc..38f9c6abc563 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -798,7 +798,7 @@ <string name="relationTypeAssistant" msgid="4057605157116589315">"Assistant"</string> <string name="relationTypeBrother" msgid="7141662427379247820">"Frère"</string> <string name="relationTypeChild" msgid="9076258911292693601">"Enfant"</string> - <string name="relationTypeDomesticPartner" msgid="7825306887697559238">"Compagne/Compagnon"</string> + <string name="relationTypeDomesticPartner" msgid="7825306887697559238">"Compagnon/Compagne"</string> <string name="relationTypeFather" msgid="3856225062864790596">"Père"</string> <string name="relationTypeFriend" msgid="3192092625893980574">"Ami(e)"</string> <string name="relationTypeManager" msgid="2272860813153171857">"Gestionnaire"</string> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Demande de <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Oui"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Non"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Accès d\'urgence à la position"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Le fabricant de votre appareil a accédé à votre position durant une session d\'urgence récente"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Votre fournisseur de services a accédé à votre position durant une session d\'urgence récente"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Le nombre maximal de suppressions a été atteint."</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> éléments vont être supprimés lors de la synchronisation <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> pour le compte <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Voulez-vous continuer?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Supprimer les éléments"</string> @@ -2032,7 +2029,7 @@ <item quantity="one"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichier</item> <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichiers</item> </plurals> - <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personne pour le partage direct"</string> + <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personnes avec lesquelles effectuer un partage"</string> <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Liste des applications"</string> <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Cette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait capturer du contenu audio par l\'intermédiaire de cet appareil USB."</string> <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Accueil"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index f5409537ea86..86facd466c42 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -800,15 +800,15 @@ <string name="relationTypeChild" msgid="9076258911292693601">"Enfant"</string> <string name="relationTypeDomesticPartner" msgid="7825306887697559238">"Concubin"</string> <string name="relationTypeFather" msgid="3856225062864790596">"Père"</string> - <string name="relationTypeFriend" msgid="3192092625893980574">"Ami"</string> + <string name="relationTypeFriend" msgid="3192092625893980574">"Ami(e)"</string> <string name="relationTypeManager" msgid="2272860813153171857">"Responsable"</string> <string name="relationTypeMother" msgid="2331762740982699460">"Mère"</string> - <string name="relationTypeParent" msgid="4177920938333039882">"Parent"</string> - <string name="relationTypePartner" msgid="4018017075116766194">"Partenaire"</string> - <string name="relationTypeReferredBy" msgid="5285082289602849400">"Recommandé par"</string> + <string name="relationTypeParent" msgid="4177920938333039882">"Parent(e)"</string> + <string name="relationTypePartner" msgid="4018017075116766194">"Conjoint(e)"</string> + <string name="relationTypeReferredBy" msgid="5285082289602849400">"Parrain(ne)"</string> <string name="relationTypeRelative" msgid="3396498519818009134">"Proche"</string> <string name="relationTypeSister" msgid="3721676005094140671">"Sœur"</string> - <string name="relationTypeSpouse" msgid="6916682664436031703">"Conjoint"</string> + <string name="relationTypeSpouse" msgid="6916682664436031703">"Époux(se)"</string> <string name="sipAddressTypeCustom" msgid="6283889809842649336">"Personnalisée"</string> <string name="sipAddressTypeHome" msgid="5918441930656878367">"Domicile"</string> <string name="sipAddressTypeWork" msgid="7873967986701216770">"Professionnelle"</string> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Demande de <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Oui"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Non"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Accès à la localisation d\'urgence"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Le fabricant de votre appareil a accédé à votre position récemment lors d\'une situation d\'urgence"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Votre opérateur a accédé à votre position récemment lors d\'une situation d\'urgence"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Le nombre maximal de suppressions a été atteint."</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> éléments vont être supprimés lors de la synchronisation <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> pour le compte <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Que voulez-vous faire ?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Supprimer les éléments"</string> @@ -1795,8 +1792,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Mis à jour par votre administrateur"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Supprimé par votre administrateur"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Pour prolonger l\'autonomie de la batterie, l\'économiseur de batterie :\n· active le thème sombre ;\n· désactive ou restreint les activités en arrière-plan, certains effet visuels et d\'autres fonctionnalités, comme \"Ok Google\".\n\n"<annotation id="url">"En savoir plus"</annotation></string> - <string name="battery_saver_description" msgid="7618492104632328184">"Pour prolonger l\'autonomie de la batterie, l\'économiseur de batterie :\n· active le thème sombre ;\n· désactive ou restreint les activités en arrière-plan, certains effet visuels et d\'autres fonctionnalités, comme \"Ok Google\"."</string> + <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Pour prolonger l\'autonomie de la batterie, l\'économiseur de batterie :\n· active le thème sombre ;\n· désactive ou restreint les activités en arrière-plan, certains effets visuels et d\'autres fonctionnalités, comme \"Ok Google\".\n\n"<annotation id="url">"En savoir plus"</annotation></string> + <string name="battery_saver_description" msgid="7618492104632328184">"Pour prolonger l\'autonomie de la batterie, l\'économiseur de batterie :\n· active le thème sombre ;\n· désactive ou restreint les activités en arrière-plan, certains effets visuels et d\'autres fonctionnalités, comme \"Ok Google\"."</string> <string name="data_saver_description" msgid="4995164271550590517">"Pour réduire la consommation de données, l\'économiseur de données empêche certaines applications d\'envoyer ou de recevoir des données en arrière-plan. Ainsi, les applications que vous utilisez peuvent toujours accéder aux données, mais pas en permanence. Par exemple, il se peut que les images ne s\'affichent pas tant que vous n\'appuyez pas dessus."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Activer l\'économiseur de données ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Activer"</string> @@ -2032,7 +2029,7 @@ <item quantity="one"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichier</item> <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichiers</item> </plurals> - <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune personne trouvée pour le partage direct"</string> + <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personnes avec lesquelles effectuer un partage"</string> <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Liste des applications"</string> <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Cette application n\'a pas reçu l\'autorisation d\'enregistrer des contenus audio, mais peut le faire via ce périphérique USB."</string> <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Accueil"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 714bb7ce5317..c7cdd1351e05 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Si"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Non"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Localización: accedeuse nunha emerxencia"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"O fabricante do teu dispositivo accedeu á túa localización durante unha sesión de emerxencia recente"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"O teu operador accedeu á túa localización durante unha sesión de emerxencia recente"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Superouse o límite de elementos eliminados"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Hai <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elementos eliminados de <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, conta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Que queres facer?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Eliminar os elementos"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 191bf18a587e..07e14fefd85e 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) દ્વારા વિનંતી કરાઈ"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"હા"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"નહીં"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"ઇમર્જન્સી સમયના સ્થાનને ઍક્સેસ કર્યુ"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"તાજેતરના ઇમર્જન્સી સેશન દરમ્યાન તમારા ડિવાઇસ નિર્માતાએ તમારા સ્થાનને ઍક્સેસ કર્યુ હતું"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"તાજેતરના ઇમર્જન્સી સેશન દરમ્યાન તમારા મોબાઇલ ઑપરેટરે તમારા સ્થાનને ઍક્સેસ કર્યુ હતું"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"કાઢી નાખવાની સીમા ઓળંગાઈ"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, એકાઉન્ટ <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> માટે <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> કાઢી નાખેલ આઇટમ્સ છે. તમે શું કરવા માગો છો?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"આઇટમ્સ કાઢી નાખો"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index a52d56420e27..ee4741ce1b65 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) द्वारा अनुरोधित"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"हां"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"नहीं"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"आपातकालीन स्थिति में जगह की जानकारी ऐक्सेस की गई"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"हाल ही में हुए आपातकालीन स्थिति के दौरान, डिवाइस बनाने वाली कंपनी ने आपकी जगह की जानकारी को ऐक्सेस किया"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"हाल ही में आपातकालीन स्थिति के दौरान, मोबाइल और इंटरनेट सेवा देने वाली कंपनी ने आपकी जगह की जानकारी को ऐक्सेस किया"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"हटाने की सीमा पार हो गई"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> खाते के <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> आइटम हटा दिए गए हैं. आप क्या करना चाहते हैं?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"आइटम मिटाएं"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index f6cb875d43f1..b446c2779228 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1478,12 +1478,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Zatražio <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Da"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Ne"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Pristup lokaciji tijekom hitnog slučaja"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Proizvođač vašeg uređaja pristupio je vašoj lokaciji tijekom nedavne hitne sesije"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Vaš mobilni operater pristupio je vašoj lokaciji tijekom nedavne hitne sesije"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Prekoračeno je ograničenje za brisanje"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Postoji sljedeći broj izbrisanih stavki: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> za vrstu sinkronizacije <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> i račun <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Što želite učiniti?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Izbriši ove stavke"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index a88dd2832398..179531530f97 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Igénylő <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Igen"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nem"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Vészhelyzeti helyadat-hozzáférés"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Eszköze gyártója hozzáfért a helyadataihoz egy közelmúltbeli vészhelyzet során"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Szolgáltatója hozzáfért a helyadataihoz egy közelmúltbeli vészhelyzet során"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"A szinkronizálás elérte a törlésre vonatkozó korlátot"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> törölt elem van a(z) (<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>) <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> fióknál. Mit szeretne tenni?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Az elemek törlése"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 42e131634e10..441a2ee7ba6e 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)-ի հարցումով"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Այո"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Ոչ"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Օգտագործվել են տեղադրության տվյալները"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Ձեր սարքի արտադրողը վերջին շտապ կանչի ժամանակ օգտագործել է ձեր տեղադրության մասին տվյալները"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Ձեր օպերատորը վերջին շտապ կանչի ժամանակ օգտագործել է ձեր տեղադրության մասին տվյալները"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Ջնջելու սահմանը գերազանցվել է"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ջնջված տարր կա <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>-ի համար, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>-ի հաշիվ: Ի՞նչ եք ցանկանում անել:"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Ջնջել տարրերը"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 3d6791fb544f..b6ff57b11181 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Diminta oleh <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ya"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Tidak"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Lokasi darurat diakses"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Operator perangkat mengakses lokasi selama sesi darurat baru-baru ini"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Operator mengakses lokasi selama sesi darurat baru-baru ini"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Penghapusan melebihi batas"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Terdapat <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> item yang dihapus untuk <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, akun <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Apa yang ingin Anda lakukan?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Hapus item"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 85926d265586..6c017e83adf7 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Beiðni frá <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Já"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nei"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Aðgangur að staðsetningu"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Framleiðandi tækisins fékk aðgang að staðsetningu þinni í nýlegri neyðarlotu"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Símafyrirtækið þitt fékk aðgang að staðsetningu þinni í nýlegri neyðarlotu"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Hámarki eyðinga náð"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> atriðum hefur verið eytt fyrir <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> á reikningnum <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Hvað viltu gera?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Eyða atriðunum"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index bddd1ae3adcd..f656326a10f4 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Richiesto da <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Sì"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"No"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Posizione usata durante un\'emergenza"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Il produttore del dispositivo ha usato la tua posizione durante una recente sessione di emergenza"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"L\'operatore ha usato la tua posizione durante una recente sessione di emergenza"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Limite di eliminazioni superato"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Ci sono <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elementi eliminati per <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> . Come vuoi procedere?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Elimina gli elementi"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 3c57bc574c97..87b670a82e96 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1499,12 +1499,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"מבוקש על ידי <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"כן"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"לא"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"בוצעה גישה למיקום בזמן מקרה חירום"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"יצרן המכשיר שלך ניגש לנתוני המיקום שלך במהלך פעילות במקרה חירום לאחרונה"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"הספק שלך ניגש לנתוני המיקום שלך במהלך פעילות במקרה חירום לאחרונה"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"חרגת ממגבלת המחיקה"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"יש <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> פריטים שנמחקו עבור <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> , בחשבון <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. איזו פעולה ברצונך לבצע?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"מחק את הפריטים"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index d68f6cf5e20e..17924e47a920 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g>さん(<xliff:g id="SERVICE">%2$s</xliff:g>)からのリクエスト"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"はい"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"いいえ"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"緊急対応時に位置情報にアクセスされました"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"最近の緊急対応時にデバイス メーカーが位置情報にアクセスしました"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"最近の緊急対応時に携帯通信会社が位置情報にアクセスしました"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"削除の制限を超えました"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>アカウントの<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>で<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>件の削除があります。操作を選択してください。"</string> <string name="sync_really_delete" msgid="5657871730315579051">"アイテムを削除する"</string> @@ -2012,7 +2009,7 @@ <string name="mime_type_apk" msgid="3168784749499623902">"Android アプリ"</string> <string name="mime_type_generic" msgid="4606589110116560228">"ファイル"</string> <string name="mime_type_generic_ext" msgid="9220220924380909486">"<xliff:g id="EXTENSION">%1$s</xliff:g> ファイル"</string> - <string name="mime_type_audio" msgid="4933450584432509875">"音声"</string> + <string name="mime_type_audio" msgid="4933450584432509875">"オーディオ"</string> <string name="mime_type_audio_ext" msgid="2615491023840514797">"<xliff:g id="EXTENSION">%1$s</xliff:g> 音声"</string> <string name="mime_type_video" msgid="7071965726609428150">"動画"</string> <string name="mime_type_video_ext" msgid="185438149044230136">"<xliff:g id="EXTENSION">%1$s</xliff:g> 動画"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index d8f5bb8d973d..9c852857cb8e 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"მოთხოვნილია <xliff:g id="NAME">%1$s</xliff:g>-ის მიერ (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"დიახ"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"არა"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"დაფიქსირდა წვდომა საგანგებო მდებარეობაზე"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"დაფიქსირდა თქვენი მოწყობილობის მწარმოებლის წვდომა თქვენს მდებარეობაზე ბოლოდროინდელი საგანგებო სესიის განმავლობაში"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"დაფიქსირდა თქვენი ოპერატორის წვდომა თქვენს მდებარეობაზე ბოლოდროინდელი საგანგებო სესიის განმავლობაში"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"წაშლის შეზღუდვა გადაჭარბებულია"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> წაშლილი ერთეულია <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>-თვის, ანგარიში <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. რისი გაკეთება გსურთ?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"ერთეულების წაშლა"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 96e7060697d4..d2773a2f69a1 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Өтініш жіберген <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Иә"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Жоқ"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Геодерегіңіз пайдаланылды."</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Жақында құтқару қызметіне қоңырау шалғанда, құрылғы өндірушісі геодерегіңізді пайдаланды."</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Жақында құтқару қызметіне қоңырау шалғанда, оператор геодерегіңізді пайдаланды."</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Жою шектеуінен асып кетті"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Мұнда <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> жойылған <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> есептік жазбасының элементі бар. Не істеуді қалайсыз?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Бұл нәрселер жойылсын"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 81a324edbd24..3b48199e537d 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -1459,12 +1459,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"បានស្នើដោយ <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"បាទ/ចាស"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"ទេ"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"បានចូលប្រើទីតាំងពេលមានអាសន្ន"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"ក្រុមហ៊ុនផលិតឧបករណ៍របស់អ្នកបានចូលប្រើទីតាំងរបស់អ្នក អំឡុងវគ្គពេលមានអាសន្នថ្មីៗ"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"ក្រុមហ៊ុនសេវាទូរសព្ទរបស់អ្នកបានចូលប្រើទីតាំងរបស់អ្នក អំឡុងវគ្គពេលមានអាសន្នថ្មីៗ"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"លុបលើសដែនកំណត់"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"មានធាតុបានលុប <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> សម្រាប់ <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> គណនី <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> ។ តើអ្នកចង់ធ្វើអ្វីខ្លះ?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"លុបធាតុ"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 07342c0a249c..64002ef0d15f 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -1091,7 +1091,7 @@ <string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string> <string name="selectAll" msgid="1532369154488982046">"ಎಲ್ಲವನ್ನೂ ಆಯ್ಕೆ ಮಾಡಿ"</string> <string name="cut" msgid="2561199725874745819">"ಕತ್ತರಿಸು"</string> - <string name="copy" msgid="5472512047143665218">"ನಕಲಿಸು"</string> + <string name="copy" msgid="5472512047143665218">"ನಕಲಿಸಿ"</string> <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"ಕ್ಲಿಪ್ಬೋರ್ಡ್ಗೆ ನಕಲಿಸಲು ವಿಫಲವಾಗಿದೆ"</string> <string name="paste" msgid="461843306215520225">"ಅಂಟಿಸಿ"</string> <string name="paste_as_plain_text" msgid="7664800665823182587">"ಸರಳ ಪಠ್ಯದಂತೆ ಅಂಟಿಸು"</string> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) ಅವರಿಂದ ವಿನಂತಿಸಲಾಗಿದೆ"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"ಹೌದು"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"ಇಲ್ಲ"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"ತುರ್ತು ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಲಾಗಿದೆ"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"ಇತ್ತೀಚಿನ ತುರ್ತು ಸೆಶನ್ನ ಸಮಯದಲ್ಲಿ ನಿಮ್ಮ ಸಾಧನದ ತಯಾರಕರು ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿದರು"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"ಇತ್ತೀಚಿನ ತುರ್ತು ಸೆಶನ್ನ ಸಮಯದಲ್ಲಿ ನಿಮ್ಮ ವಾಹಕ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿದೆ"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"ಅಳಿಸುವ ಮಿತಿ ಮೀರಿದೆ"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> ಗಾಗಿ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ಅಳಿಸಲಾಗಿರುವ ಐಟಂಗಳು ಕಂಡುಬಂದಿವೆ. ನೀವು ಏನು ಮಾಡಬೇಕೆಂದು ಬಯಸುವಿರಿ?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"ಐಟಂಗಳನ್ನು ಅಳಿಸಿ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 0a56fb675e1c..ac691ae1189c 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -803,7 +803,7 @@ <string name="relationTypeFriend" msgid="3192092625893980574">"친구"</string> <string name="relationTypeManager" msgid="2272860813153171857">"상사"</string> <string name="relationTypeMother" msgid="2331762740982699460">"어머니"</string> - <string name="relationTypeParent" msgid="4177920938333039882">"부모"</string> + <string name="relationTypeParent" msgid="4177920938333039882">"부모님"</string> <string name="relationTypePartner" msgid="4018017075116766194">"파트너"</string> <string name="relationTypeReferredBy" msgid="5285082289602849400">"추천인"</string> <string name="relationTypeRelative" msgid="3396498519818009134">"친척"</string> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"요청한 사람: <xliff:g id="NAME">%1$s</xliff:g>(<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"예"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"아니요"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"응급 상황 동안 위치에 액세스함"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"기기 제조업체에서 최근 응급 상황 세션 동안 내 위치에 액세스했습니다."</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"이동통신사에서 최근 응급 상황 세션 동안 내 위치에 액세스했습니다."</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"삭제 한도를 초과했습니다."</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 계정에 대해 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>개의 삭제된 항목이 있습니다. 어떻게 하시겠습니까?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"항목 삭제"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 81ede7d1b2c0..558b5ef0c1ec 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) сурады"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ооба"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Жок"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Кырсыктагандагы жайгашкан жер аныкталды"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Акыркы жолу телефон чалганыңызда түзмөктү иштеп чыгуучу кайда турганыңызды аныктады"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Акыркы жолу телефон чалганыңызда байланыш операторуңуз кайда турганыңызды аныктады"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Жок кылуу чегинен ашты"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> эсебине тиешелүү <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> боюнча <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> өчүрүлгөн элемент бар. Мындан аркы кадамдарыңыз кандай болот?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Элементтерди жок кылуу"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 60b91f76207e..5ff7a692621a 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"ຮ້ອງຂໍໂດຍ <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"ຕົກລົງ"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"ບໍ່"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"ມີການເຂົ້າເຖິງສະຖານທີ່ສຸກເສີນ"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"ຜູ້ຜະລິດອຸປະກອນຂອງທ່ານເຂົ້າເຖິງສະຖານທີ່ທ່ານໃນລະຫວ່າງຊ່ວງເວລາສຸກເສີນຫຼ້າສຸດຂອງທ່ານ"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"ຜູ້ໃຫ້ບໍລິການຂອງທ່ານເຂົ້າເຖິງສະຖານທີ່ທ່ານໃນລະຫວ່າງຊ່ວງເວລາສຸກເສີນຫຼ້າສຸດຂອງທ່ານ"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"ກາຍເຂດກຳນົດການລຶບ"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"ມີ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ລາຍການທີ່ຖືກລຶບສຳລັບ <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, ບັນຊີ <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. ທ່ານຕ້ອງການຈະເຮັດແນວໃດ?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"ລຶບລາຍການ"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 6efae067b8aa..2b041565f416 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -1499,12 +1499,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Užklausą pateikė <xliff:g id="NAME">%1$s</xliff:g> („<xliff:g id="SERVICE">%2$s</xliff:g>“)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Taip"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Ne"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Pasiekta kritinės padėties vietovės inf."</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Įrenginio gamintojas pasiekė jūsų vietovės duomenis per naujausią kritinės padėties seansą"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Operatorius pasiekė jūsų vietovės duomenis per naujausią kritinės padėties seansą"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Viršytas ištrynimo apribojimas"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Yra <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ištr. element., skirt. <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, „<xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>“ pask. Ką norite daryti?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Ištrinti elementus"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index aad9a69cb136..c80e3ac45e99 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1478,12 +1478,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Pieprasīja: <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Jā"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nē"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Piekļuve atrašanās vietai ārkārtas brīdī"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Jūsu ierīces ražotājs piekļuva jūsu atrašanās vietai nesena ārkārtas izsaukuma laikā."</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Jūsu mobilo sakaru operators piekļuva jūsu atrašanās vietai nesena ārkārtas izsaukuma laikā."</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Pārsniegts dzēšanas ierobežojums"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, konts <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>: izdzēsti <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> vienumi. Kādas darbības vēlaties veikt?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Dzēsiet šos vienumus."</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 9eb7aac45613..f7e23a8ad1ac 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Побарано од <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Да"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Не"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Пристапено до локацијата за итни случаи"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Производителот на уредот пристапи до вашата локација при неодамнешна итна сесија"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Операторот пристапи до вашата локација при неодамнешна итна сесија"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Границата на бришење е надмината"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Постојат <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> избришани ставки за <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> сметка. Што сакате да направите?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Избриши ги ставките"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 5b56aa7c3710..3c76caf408a0 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -239,7 +239,7 @@ <string name="global_action_power_off" msgid="4404936470711393203">"പവർ ഓഫാക്കുക"</string> <string name="global_action_power_options" msgid="1185286119330160073">"പവർ"</string> <string name="global_action_restart" msgid="4678451019561687074">"റീസ്റ്റാർട്ട് ചെയ്യുക"</string> - <string name="global_action_emergency" msgid="1387617624177105088">"അടിയന്തിരാവശ്യം"</string> + <string name="global_action_emergency" msgid="1387617624177105088">"അടിയന്തരാവശ്യം"</string> <string name="global_action_bug_report" msgid="5127867163044170003">"ബഗ് റിപ്പോർട്ട്"</string> <string name="global_action_logout" msgid="6093581310002476511">"സെഷൻ അവസാനിപ്പിക്കുക"</string> <string name="global_action_screenshot" msgid="2610053466156478564">"സ്ക്രീൻഷോട്ട്"</string> @@ -1652,7 +1652,7 @@ <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"കുറുക്കുവഴി ഓഫാക്കുക"</string> <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"കുറുക്കുവഴി ഉപയോഗിക്കുക"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"വർണ്ണ വിപര്യയം"</string> - <string name="color_correction_feature_name" msgid="3655077237805422597">"വർണ്ണം ക്രമീകരിക്കൽ"</string> + <string name="color_correction_feature_name" msgid="3655077237805422597">"നിറം ക്രമീകരിക്കൽ"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"വോളിയം കീകൾ പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കി."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"വോളിയം കീകൾ പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫാക്കി."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഉപയോഗിക്കാൻ, രണ്ട് വോളിയം കീകളും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index ac29610b3774..f9963435bbaf 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) хүсэлт илгээсэн"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Тийм"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Үгүй"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Яаралтай тусламжийн байршилд хандсан"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Таны төхөөрөмжийн үйлдвэрлэгч саяхны яаралтай тусламжийн харилцан үйлдлийн үеэр таны байршилд хандсан байна"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Таны оператор компани саяхны яаралтай тусламжийн харилцан үйлдлийн үеэр таны байршилд хандсан байна"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Устгах хязгаар хэтрэв"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>-р <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> бүртгэлийн <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> зүйл устсан . Та юу хиймээр байна?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Устгах"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index cc66d3b0c129..8a4148a91d6a 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Diminta oleh <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ya"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Tidak"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Lokasi kecemasan diakses"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Pengilang peranti anda mengakses lokasi anda semasa sesi kecemasan baru-baru ini"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Pembawa anda mengakses lokasi anda semasa sesi kecemasan baru-baru ini"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Melebihi had padam"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Terdapat <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> item yang dipadamkan untuk <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, akaun <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Apakah yang mahu anda lakukan?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Padamkan item itu"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index cd7d9db713a0..7c6f3e72f9cc 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -1447,7 +1447,7 @@ </plurals> <string name="action_mode_done" msgid="2536182504764803222">"ပြီးပါပြီ"</string> <string name="progress_erasing" msgid="6891435992721028004">"မျှဝေထားသည့် သိုလှောင်ခန်းကို ဖျက်နေသည်…"</string> - <string name="share" msgid="4157615043345227321">"မျှဝေခြင်း"</string> + <string name="share" msgid="4157615043345227321">"မျှဝေရန်"</string> <string name="find" msgid="5015737188624767706">"ရှာဖွေရန်"</string> <string name="websearch" msgid="5624340204512793290">"ဝဘ်တွင် ရှာရန်"</string> <string name="find_next" msgid="5341217051549648153">"နောက်တစ်ခု ရှာဖွေရန်"</string> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)မှတောင်းခံသည်"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Yes"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"No"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"အရေးပေါ် တည်နေရာကို ဝင်ကြည့်ထားသည်"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"မကြာသေးမီက အရေးပေါ်စက်ရှင်တွင် သင်၏စက်ပစ္စည်းထုတ်လုပ်သူသည် သင့်တည်နေရာကို ဝင်ကြည့်ထားသည်"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"မကြာသေးမီက အရေးပေါ်စက်ရှင်တွင် သင်၏ဝန်ဆောင်မှုပေးသူသည် သင့်တည်နေရာကို ဝင်ကြည့်ထားသည်"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"ပယ်ဖျက်မည့်ကန့်သတ်နှုန်းကျော်လွန်သည်"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>၊ account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> အတွက် စုစုပေါင်း <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> အရာဖျက်ထားပါသည်။ သင်ဘာလုပ်ချင်ပါလဲ?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"ဤအရာများကိုဖျက်ပါ"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index a398bca2a62a..9f75ce2217f2 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Forespurt av <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ja"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nei"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Posisjonen ble sjekket i nødssituasjon"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Enhetsprodusenten din sjekket posisjonen din under en nylig nødssituasjonsøkt"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Operatøren din sjekket posisjonen din under en nylig nødssituasjonsøkt"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Slettegrense overskredet"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Det fins <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> slettede elementer for <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> for kontoen <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Hva ønsker du å gjøre?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Slett elementene"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 20461de2c867..17989bff6ebc 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Aangevraagd door <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ja"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nee"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Locatie bekeken tijdens noodsituatie"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"De fabrikant van je apparaat heeft toegang gehad tot je locatie tijdens een recente noodsessie"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Je provider heeft toegang gehad tot je locatie tijdens een recente noodsessie"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Verwijderingslimiet overschreden"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Er zijn <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> verwijderde items voor <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> , account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> . Wat wil je doen?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"De items verwijderen."</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 40e9e12655f9..57e167b948b6 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -1327,7 +1327,7 @@ <string name="share_remote_bugreport_action" msgid="7630880678785123682">"ସେୟାର୍ କରନ୍ତୁ"</string> <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ପ୍ରତ୍ୟାଖ୍ୟାନ କରନ୍ତୁ"</string> <string name="select_input_method" msgid="3971267998568587025">"ଇନପୁଟ୍ ପଦ୍ଧତି ବାଛନ୍ତୁ"</string> - <string name="show_ime" msgid="6406112007347443383">"ଫିଜିକାଲ୍ କୀ’ବୋର୍ଡ ସକ୍ରିୟ ଥିବାବେଳେ ଏହାକୁ ସ୍କ୍ରୀନ୍ ଉପରେ ରଖନ୍ତୁ"</string> + <string name="show_ime" msgid="6406112007347443383">"ଫିଜିକାଲ୍ କୀବୋର୍ଡ ସକ୍ରିୟ ଥିବାବେଳେ ଏହାକୁ ସ୍କ୍ରିନ୍ ଉପରେ ରଖନ୍ତୁ"</string> <string name="hardware" msgid="1800597768237606953">"ଭର୍ଚୁଆଲ୍ କୀ’ବୋର୍ଡ ଦେଖାନ୍ତୁ"</string> <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"ଫିଜିକଲ୍ କୀ\'ବୋର୍ଡ କନଫିଗର୍ କରନ୍ତୁ"</string> <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ଭାଷା ଓ ଲେଆଉଟ୍ ଚୟନ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string> @@ -1878,7 +1878,7 @@ <string name="notification_history_title_placeholder" msgid="7748630986182249599">"କଷ୍ଟମ୍ ଆପ୍ ବିଜ୍ଞପ୍ତି"</string> <string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ (ପୂର୍ବରୁ ଏହି ଆକାଉଣ୍ଟ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ନାମରେ ଅଛି) ଅନୁମତି ଦେବେ?"</string> <string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string> - <string name="language_selection_title" msgid="52674936078683285">"ଏକ ଭାଷା ଯୋଡ଼ନ୍ତୁ"</string> + <string name="language_selection_title" msgid="52674936078683285">"ଏକ ଭାଷା ଯୋଗ କରନ୍ତୁ"</string> <string name="country_selection_title" msgid="5221495687299014379">"ପସନ୍ଦର ଅଞ୍ଚଳ"</string> <string name="search_language_hint" msgid="7004225294308793583">"ଭାଷାର ନାମ ଟାଇପ୍ କରନ୍ତୁ"</string> <string name="language_picker_section_suggested" msgid="6556199184638990447">"ପ୍ରସ୍ତାବିତ"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index e5353112cb7b..4735b57c4bb1 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -1564,7 +1564,7 @@ <string name="wireless_display_route_description" msgid="8297563323032966831">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ"</string> <string name="media_route_button_content_description" msgid="2299223698196869956">"ਪ੍ਰਸਾਰਿਤ ਕਰੋ"</string> <string name="media_route_chooser_title" msgid="6646594924991269208">"ਡੀਵਾਈਸ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string> - <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"ਡੀਵਾਈਸ ਨਾਲ ਸਕ੍ਰੀਨ ਕਾਸਟ ਕਰੋ"</string> + <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"ਡੀਵਾਈਸ \'ਤੇ ਸਕ੍ਰੀਨ ਕਾਸਟ ਕਰੋ"</string> <string name="media_route_chooser_searching" msgid="6119673534251329535">"ਡੀਵਾਈਸਾਂ ਦੀ ਖੋਜ ਹੋ ਰਹੀ ਹੈ…"</string> <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"ਸੈਟਿੰਗਾਂ"</string> <string name="media_route_controller_disconnect" msgid="7362617572732576959">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index b052be45d414..f219bd3ac143 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1499,12 +1499,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Żądane przez <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Tak"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nie"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Uzyskano alarmowy dostęp do lokalizacji"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Producent Twojego urządzenia uzyskał dostęp do Twojej lokalizacji podczas ostatniej sytuacji alarmowej"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Twój operator uzyskał dostęp do Twojej lokalizacji podczas ostatniej sytuacji alarmowej"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Przekroczono limit usuwania"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Usuwasz <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elementy(ów) przez: <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> (konto: <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>). Co chcesz zrobić?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Usuń elementy."</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index a839a4241515..1354a371f2e5 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Sim"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Não"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Acesso ao local de emergência"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"O fabricante do dispositivo acessou seu local durante uma sessão de emergência recente"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"A operadora acessou seu local durante uma sessão de emergência recente"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Limite de exclusão excedido"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Há <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> itens excluídos para <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, conta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. O que você quer fazer?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Excluir os itens"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index fb7a14c28592..b5d2e99593b1 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Pedido por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Sim"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Não"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Acesso à localização de emergência"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"O fabricante do seu dispositivo acedeu à sua localização durante uma sessão de emergência recente."</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"O seu operador acedeu à sua localização durante uma sessão de emergência recente."</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Limite de eliminações excedido"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Há <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> itens eliminados de <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, conta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. O que pretende fazer?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Eliminar os itens"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index a839a4241515..1354a371f2e5 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Sim"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Não"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Acesso ao local de emergência"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"O fabricante do dispositivo acessou seu local durante uma sessão de emergência recente"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"A operadora acessou seu local durante uma sessão de emergência recente"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Limite de exclusão excedido"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Há <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> itens excluídos para <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, conta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. O que você quer fazer?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Excluir os itens"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 4867642f73c6..73c3e42696dc 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1478,12 +1478,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Solicitat de <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Da"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nu"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"A fost accesată locația de urgență"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Producătorul dispozitivului v-a accesat locația în timpul unei sesiuni de urgență recente"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Operatorul v-a accesat locația în timpul unei sesiuni de urgență recente"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Limita pentru ștergere a fost depășită"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Există <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elemente șterse pentru <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, contul <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Ce doriți să faceți?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Ștergeți elementele"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 6ecf5811ccc8..7b2e882d5331 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1499,12 +1499,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Запрашивает <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Да"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Нет"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Получен доступ к вашим геоданным"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Производитель устройства получил доступ к данным о вашем местоположении во время недавней передачи сведений в экстренной ситуации."</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Оператор получил доступ к данным о вашем местоположении во время недавней передачи сведений в экстренной ситуации."</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Превышен предел удаления"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Удаленных объектов для <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>, аккаунт <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Что нужно сделать?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Удалить"</string> @@ -2100,7 +2097,7 @@ <item quantity="many">\"<xliff:g id="FILE_NAME_2">%s</xliff:g>\" и ещё <xliff:g id="COUNT_3">%d</xliff:g> файлов</item> <item quantity="other">\"<xliff:g id="FILE_NAME_2">%s</xliff:g>\" и ещё <xliff:g id="COUNT_3">%d</xliff:g> файла</item> </plurals> - <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Рекомендованных пользователей нет."</string> + <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Рекомендованных получателей нет."</string> <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Список приложений"</string> <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Приложению не разрешено записывать звук, однако оно может делать это с помощью этого USB-устройства."</string> <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Главный экран"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index eaa93bf03985..3a8639e1e2f1 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -1459,12 +1459,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) විසින් ඉල්ලන ලද"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"ඔව්"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"නැත"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"හදිසි අවස්ථා ස්ථානය වෙත ප්රවේශ විය"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"මෑත හදිසි අවස්ථා සැසියක් අතරතුර ඔබගේ උපාංග නිෂ්පාදක ඔබගේ ස්ථානයට ප්රවේශ විය"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"මෑත හදිසි අවස්ථා සැසියක් අතරතුර ඔබගේ වාහකය ඔබගේ ස්ථානයට ප්රවේශ විය"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"මැකීමේ සීමාව ඉක්මවන ලදි"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> සඳහා <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> ගිණුමේ මකන ලද අයිතම <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ක් ඇත. ඔබට කුමක් කිරීමට අවශ්යද?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"අයිතම මකන්න"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index e55235854871..dee51d552503 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1499,12 +1499,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Žiadosť od používateľa <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Áno"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nie"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Bola použitá poloha v tiesni"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Výrobca vášho zariadenia použil vašu polohu počas nedávnej relácie v tiesňovej situácii"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Váš operátor použil vašu polohu počas nedávnej relácie v tiesňovej situácii"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Bol prekročený limit odstraňovania"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Počet odstránených položiek pre <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> účet <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> je: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Čo chcete robiť?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Odstrániť položky"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 7d7b0e981964..1511c18ced9f 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1499,12 +1499,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Zahtevala oseba <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Da"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Ne"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Dostop do lokacije med klicem v sili"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Med nedavnim klicem v sili je proizvajalec naprave dostopil do vaše lokacije"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Med nedavnim klicem v sili je operater dostopil do vaše lokacije"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Omejitev brisanja je presežena"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Št. izbrisanih elementov za <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> v računu <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Kaj želite narediti?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Izbris elementov"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 085a0eb539f7..6bf4306ed2d3 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Kërkuar nga <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Po"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Jo"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Pati qasje në vendndodhjen e urgjencës"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Prodhuesi i pajisjes sate u qas në vendndodhjen tënde gjatë një sesioni të fundit urgjence"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Operatori yt celular u qas në vendndodhjen tënde gjatë një sesioni të fundit urgjence"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Kufiri i fshirjes u tejkalua"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Ka <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> artikuj të fshirë për <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> nga llogaria <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Çfarë dëshiron të bësh?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Fshiji artikujt"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 55c1fef37664..9f0dfb1baf0f 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1478,12 +1478,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Захтева <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Да"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Не"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Приступљено локацији за хитне случајеве"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Произвођач уређаја је приступио вашој локацији током недавне хитне сесије"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Мобилни оператер је приступио вашој локацији током недавне хитне сесије"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Премашено је ограничење за брисање"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Постоје избрисане ставке (<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>) за <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, налог <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Шта желите да урадите?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Избриши ставке"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 4e9c1fa62b7b..2e6a848be5cc 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Begärt av <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ja"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Nej"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Åtkomst till platsen för nödsituationen"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Din enhetstillverkare kom åt till din plats vid en nödsituation nyligen"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Din operatör kom åt till din plats vid en nödsituation nyligen"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Gränsen för borttagning har överskridits"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Det finns <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> borttagna objekt för <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, konto <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Vad vill du göra?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Ta bort objekten"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index f26ce70a24ac..1b5d6718b507 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Imeombwa na <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ndiyo"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Hapana"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Eneo lilifikiwa wakati wa dharura"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Mtengenezaji wa kifaa chako alifikia maelezo ya mahali ulipo wakati wa dharura hivi majuzi"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Mtoa huduma wako alifikia maelezo ya mahali ulipo wakati wa dharura hivi majuzi"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Upeo wa ufutaji umezidishwa"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Kuna vipengee <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> vilivyofutwa vya <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, akaunti <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Je, unataka kufanya nini?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Futa vipengee"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 71072f883cf1..2a03f365e9d7 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) ஆல் கோரப்பட்டுள்ளது"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"ஆம்"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"இல்லை"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"அவசரகாலத்திற்காக இருப்பிடம் அணுகப்பட்டது"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"சமீபத்திய அவசர அமர்வின் போது உங்கள் சாதனத்தின் உற்பத்தியாளர் உங்களது இருப்பிடத்தை அணுகினார்"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"சமீபத்திய அவசர அமர்வின்போது உங்கள் மொபைல் நிறுவனம் உங்களது இருப்பிடத்தை அணுகியது"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"நீக்கும் வரம்பு கடந்தது"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> கணக்கின் <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> க்கான <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> நீக்கப்பட்ட உருப்படிகள் உள்ளன. என்ன செய்ய விரும்புகிறீர்கள்?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"உருப்படிகளை நீக்கு"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 01a60b0244f4..f848950c82af 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -1565,7 +1565,7 @@ <string name="media_route_button_content_description" msgid="2299223698196869956">"ప్రసారం చేయండి"</string> <string name="media_route_chooser_title" msgid="6646594924991269208">"పరికరానికి కనెక్ట్ చేయండి"</string> <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"స్క్రీన్ను పరికరానికి ప్రసారం చేయండి"</string> - <string name="media_route_chooser_searching" msgid="6119673534251329535">"పరికరాల కోసం వెతుకుతోంది…"</string> + <string name="media_route_chooser_searching" msgid="6119673534251329535">"డివైజ్ల కోసం వెతుకుతోంది…"</string> <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"సెట్టింగ్లు"</string> <string name="media_route_controller_disconnect" msgid="7362617572732576959">"డిస్కనెక్ట్ చేయి"</string> <string name="media_route_status_scanning" msgid="8045156315309594482">"స్కాన్ చేస్తోంది..."</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index ad11d6bcbb4c..ff5557de5e91 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -803,7 +803,7 @@ <string name="relationTypeFriend" msgid="3192092625893980574">"เพื่อน"</string> <string name="relationTypeManager" msgid="2272860813153171857">"ผู้จัดการ"</string> <string name="relationTypeMother" msgid="2331762740982699460">"มารดา"</string> - <string name="relationTypeParent" msgid="4177920938333039882">"บิดามารดา"</string> + <string name="relationTypeParent" msgid="4177920938333039882">"ผู้ปกครอง"</string> <string name="relationTypePartner" msgid="4018017075116766194">"หุ้นส่วน"</string> <string name="relationTypeReferredBy" msgid="5285082289602849400">"แนะนำโดย"</string> <string name="relationTypeRelative" msgid="3396498519818009134">"ญาติ"</string> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"ร้องขอโดย <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"ใช่"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"ไม่"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"เข้าถึงตำแหน่งฉุกเฉินแล้ว"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"ผู้ผลิตอุปกรณ์เข้าถึงตำแหน่งของคุณระหว่างเซสชันฉุกเฉินเมื่อเร็วๆ นี้"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"ผู้ให้บริการเข้าถึงตำแหน่งของคุณระหว่างเซสชันฉุกเฉินเมื่อเร็วๆ นี้"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"เกินจำนวนการนำออกสูงสุด"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"มีรายการที่จะลบ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> รายการสำหรับ <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> ในบัญชี <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> คุณต้องการทำสิ่งใด"</string> <string name="sync_really_delete" msgid="5657871730315579051">"ลบรายการ"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index fbcd155389ec..5de452546922 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Hiniling ni <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Oo"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Hindi"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Na-access ang pang-emergency na lokasyon"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Na-access ng manufacturer ng iyong device ang lokasyon mo sa kamakailang pang-emergency na session"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Na-access ng iyong carrier ang lokasyon mo sa kamakailang pang-emergency na session"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Nalagpasan na ang limitasyon sa pagtanggal"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Mayroong <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> (na) tinanggal na item para sa <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, account na <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Ano ang nais mong gawin?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"I-delete ang mga item"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 91c48d5842c4..b10d19323066 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -192,7 +192,7 @@ <string name="network_logging_notification_title" msgid="554983187553845004">"Cihaz yönetiliyor"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Kuruluşunuz bu cihazı yönetmekte olup ağ trafiğini izleyebilir. Ayrıntılar için dokunun."</string> <string name="location_changed_notification_title" msgid="3620158742816699316">"Uygulamalar konumunuza erişebilir"</string> - <string name="location_changed_notification_text" msgid="7158423339982706912">"Daha fazla bilgi edinmek için BT yöneticinizle iletişim kurun"</string> + <string name="location_changed_notification_text" msgid="7158423339982706912">"BT yöneticinizden daha fazla bilgi alabilirsiniz."</string> <string name="country_detector" msgid="7023275114706088854">"Ülke Algılayıcı"</string> <string name="location_service" msgid="2439187616018455546">"Konum Hizmeti"</string> <string name="sensor_notification_service" msgid="7474531979178682676">"Sensör Bildirim Hizmeti"</string> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> tarafından istendi (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Evet"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Hayır"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Acil durum sırasında konuma erişildi"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Yakın zamanda yaşanan bir acil durum sırasında cihaz üreticiniz konumunuza erişti"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Yakın zamanda yaşanan bir acil durum sırasında operatörünüz konumunuza erişti"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Silme sınırı aşıldı"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> hesabında <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> için <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> adet silinmiş öğe var. Ne yapmak istiyorsunuz?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Öğeleri sil"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 76dad917ab9c..f42d156ec001 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1499,12 +1499,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Запит зроблено користувачем <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Так"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Ні"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Переглянуто геодані в екстреній ситуації"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Виробник пристрою отримав доступ до ваших геоданих під час нещодавнього екстреного звернення"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Оператор отримав доступ до ваших геоданих під час нещодавнього екстреного звернення"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Перевищено ліміт видалень"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Для <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, облікового запису <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>, знайдено стільки видалених елементів: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Що робити?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Видалити елементи"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index d066793fb5dd..e7574b111c8b 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) tomonidan so‘raldi"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Ha"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Yo‘q"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Joylashuv axborotingizga ruxsat berildi"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Qurilmangiz ishlab chiqaruvchisi oxirgi favqulodda holat seansi davomida joylashuvingiz axborotidan foydalandi"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Aloqa operatoringiz oxirgi favqulodda holat seansi davomida joylashuvingiz axborotidan foydalandi"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Cheklovdan oshganlarini o‘chirish"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> hisobi <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> uchun <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>ta o‘chirilgan elementlar bor. Nima qilmoqchisiz?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Elementlarni o‘chirish"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 5d99692f68aa..3b2de1c5e691 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Được yêu cầu bởi <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Có"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Không"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Đã truy cập dữ liệu vị trí khi khẩn cấp"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Nhà sản xuất thiết bị đã truy cập vào thông tin vị trí của bạn trong một phiên khẩn cấp gần đây"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Nhà mạng đã truy cập vào thông tin vị trí của bạn trong một phiên khẩn cấp gần đây"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Đã vượt quá giới hạn xóa"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Có <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> mục đã xóa cho <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, tài khoản <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Bạn muốn thực hiện tác vụ nào?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Xóa mục"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index dda38c35ab40..dd8875944a10 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -192,7 +192,7 @@ <string name="network_logging_notification_title" msgid="554983187553845004">"设备为受管理设备"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"贵单位会管理该设备,且可能会监控网络流量。点按即可了解详情。"</string> <string name="location_changed_notification_title" msgid="3620158742816699316">"应用可以访问您的位置信息"</string> - <string name="location_changed_notification_text" msgid="7158423339982706912">"与您的 IT 管理员联系即可了解详情"</string> + <string name="location_changed_notification_text" msgid="7158423339982706912">"详情请与您的 IT 管理员联系"</string> <string name="country_detector" msgid="7023275114706088854">"国家/地区检测器"</string> <string name="location_service" msgid="2439187616018455546">"位置信息服务"</string> <string name="sensor_notification_service" msgid="7474531979178682676">"传感器通知服务"</string> @@ -844,7 +844,7 @@ <string name="lockscreen_missing_sim_instructions_long" msgid="3664999892038416334">"SIM卡缺失或无法读取。请插入SIM卡。"</string> <string name="lockscreen_permanent_disabled_sim_message_short" msgid="3812893366715730539">"SIM卡无法使用。"</string> <string name="lockscreen_permanent_disabled_sim_instructions" msgid="4358929052509450807">"您的SIM卡已永久停用。\n请与您的无线服务提供商联系,以便重新获取一张SIM卡。"</string> - <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"上一曲"</string> + <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"上一首"</string> <string name="lockscreen_transport_next_description" msgid="2931509904881099919">"下一曲"</string> <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"暂停"</string> <string name="lockscreen_transport_play_description" msgid="106868788691652733">"播放"</string> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"请求人:<xliff:g id="NAME">%1$s</xliff:g>(<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"是"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"否"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"外部实体获取了您的紧急位置信息"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"最近发生紧急情况时,您的设备制造商获取了您的位置信息"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"最近发生紧急情况时,您的运营商获取了您的位置信息"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"超出删除限制"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"帐号 <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 在进行“<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>”同步时删除了 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> 项内容。您要如何处理这些删除的内容?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"删除这些内容"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 002312ca2b34..4d790c465314 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"要求者:<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"是"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"否"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"曾存取緊急位置"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"您的裝置製造商曾在最近的緊急情況中存取您的位置"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"您的流動網絡供應商曾在最近的緊急情況中存取您的位置"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"已超過刪除上限"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"帳戶 <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 的 <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> 操作會刪除 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> 項。您要如何處理呢?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"刪除這些項目"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index fa59e3cf7b09..e18b51e91a2a 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -798,7 +798,7 @@ <string name="relationTypeAssistant" msgid="4057605157116589315">"助理"</string> <string name="relationTypeBrother" msgid="7141662427379247820">"兄弟"</string> <string name="relationTypeChild" msgid="9076258911292693601">"子女"</string> - <string name="relationTypeDomesticPartner" msgid="7825306887697559238">"同居人"</string> + <string name="relationTypeDomesticPartner" msgid="7825306887697559238">"同居伴侶"</string> <string name="relationTypeFather" msgid="3856225062864790596">"父親"</string> <string name="relationTypeFriend" msgid="3192092625893980574">"好友"</string> <string name="relationTypeManager" msgid="2272860813153171857">"經理"</string> @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"要求者:<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"是"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"否"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"外部實體存取了你的緊急位置資訊"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"你的裝置製造商在最近的緊急工作階段期間存取了你的位置資訊"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"你的電信業者在最近的緊急工作階段期間存取了你的位置資訊"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"已超過刪除上限"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"帳戶 <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 的<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>會刪除 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> 個項目。你要如何處理?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"刪除這些項目"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 054f4b1a3650..a9af563ee1e5 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1457,12 +1457,9 @@ <string name="gpsNotifMessage" msgid="7346649122793758032">"Icelwe ngu-:<xliff:g id="NAME">%1$s</xliff:g><xliff:g id="SERVICE">%2$s</xliff:g>"</string> <string name="gpsVerifYes" msgid="3719843080744112940">"Yebo"</string> <string name="gpsVerifNo" msgid="1671201856091564741">"Cha"</string> - <!-- no translation found for gnss_nfw_notification_title (5004493772059563423) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_oem (3683958907027107969) --> - <skip /> - <!-- no translation found for gnss_nfw_notification_message_carrier (815888995791562151) --> - <skip /> + <string name="gnss_nfw_notification_title" msgid="5004493772059563423">"Indawo yesimo esiphuthumayo ifinyelelwe"</string> + <string name="gnss_nfw_notification_message_oem" msgid="3683958907027107969">"Umkhiqizi wedivayisi yakho ufinyelele indawo yakho phakathi nesikhathi sakamuva sesimo esiphuthumayo"</string> + <string name="gnss_nfw_notification_message_carrier" msgid="815888995791562151">"Inkampani yenethiwekhi yakho ifinyelele indawo yakho phakathi nesikhathi sakamuva sesimo esiphuthumayo"</string> <string name="sync_too_many_deletes" msgid="6999440774578705300">"Umkhawulo wokususa ufinyelelwe"</string> <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"Kunezinto ezingu <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ezisusiwe <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, e-akhawuntini <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Ingabe ufuna ukwenzani?"</string> <string name="sync_really_delete" msgid="5657871730315579051">"Susa izintwana."</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 1a9855311518..ab79d2d91070 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -476,10 +476,6 @@ --> </string-array> - <!-- Package name for the default CellBroadcastService module [DO NOT TRANSLATE] --> - <string name="cellbroadcast_default_package" translatable="false">com.android.cellbroadcastservice - </string> - <!-- If the mobile hotspot feature requires provisioning, a package name and class name can be provided to launch a supported application that provisions the devices. @@ -1908,7 +1904,7 @@ <!-- The name of the package that will hold the call screening role by default. --> <string name="config_defaultCallScreening" translatable="false"></string> <!-- The name of the package that will hold the system gallery role. --> - <string name="config_systemGallery" translatable="false">com.android.gallery</string> + <string name="config_systemGallery" translatable="false">com.android.gallery3d</string> <!-- The name of the package that will be allowed to change its components' label/icon. --> <string name="config_overrideComponentUiPackage" translatable="false"></string> @@ -3496,10 +3492,9 @@ <!-- Do not translate. Mcc codes whose existence trigger the presence of emergency affordances--> - <integer-array name="config_emergency_mcc_codes" translatable="false"> - <item>404</item> - <item>405</item> - </integer-array> + <string-array name="config_emergency_iso_country_codes" translatable="false"> + <item>in</item> + </string-array> <!-- Package name for the device provisioning package. --> <string name="config_deviceProvisioningPackage"></string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 05c00ce51ee3..5f93506d7ba2 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -681,7 +681,6 @@ <java-symbol type="string" name="not_checked" /> <java-symbol type="array" name="config_ethernet_interfaces" /> <java-symbol type="array" name="config_wakeonlan_supported_interfaces" /> - <java-symbol type="string" name="cellbroadcast_default_package" /> <java-symbol type="string" name="config_forceVoiceInteractionServicePackage" /> <java-symbol type="string" name="config_mms_user_agent" /> <java-symbol type="string" name="config_mms_user_agent_profile_url" /> @@ -3085,7 +3084,7 @@ <java-symbol type="string" name="global_action_emergency" /> <java-symbol type="string" name="config_emergency_call_number" /> <java-symbol type="string" name="config_emergency_dialer_package" /> - <java-symbol type="array" name="config_emergency_mcc_codes" /> + <java-symbol type="array" name="config_emergency_iso_country_codes" /> <java-symbol type="string" name="config_dozeDoubleTapSensorType" /> <java-symbol type="string" name="config_dozeTapSensorType" /> @@ -3921,6 +3920,8 @@ <java-symbol type="id" name="resolver_empty_state_button" /> <java-symbol type="id" name="resolver_empty_state_progress" /> <java-symbol type="id" name="resolver_tab_divider" /> + <java-symbol type="id" name="resolver_button_bar_divider" /> + <java-symbol type="id" name="resolver_empty_state_container" /> <java-symbol type="string" name="resolver_cant_share_with_work_apps" /> <java-symbol type="string" name="resolver_cant_share_with_work_apps_explanation" /> <java-symbol type="string" name="resolver_cant_share_with_personal_apps" /> diff --git a/core/tests/benchmarks/src/android/os/ParcelStringBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelStringBenchmark.java new file mode 100644 index 000000000000..daa90c28e0c4 --- /dev/null +++ b/core/tests/benchmarks/src/android/os/ParcelStringBenchmark.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import com.google.caliper.AfterExperiment; +import com.google.caliper.BeforeExperiment; +import com.google.caliper.Param; + +public class ParcelStringBenchmark { + + @Param({"com.example.typical_package_name", "從不喜歡孤單一個 - 蘇永康/吳雨霏"}) + String mValue; + + private Parcel mParcel; + + @BeforeExperiment + protected void setUp() { + mParcel = Parcel.obtain(); + } + + @AfterExperiment + protected void tearDown() { + mParcel.recycle(); + mParcel = null; + } + + public void timeWriteString8(int reps) { + for (int i = 0; i < reps; i++) { + mParcel.setDataPosition(0); + mParcel.writeString8(mValue); + } + } + + public void timeReadString8(int reps) { + mParcel.writeString8(mValue); + + for (int i = 0; i < reps; i++) { + mParcel.setDataPosition(0); + mParcel.readString8(); + } + } + + public void timeWriteString16(int reps) { + for (int i = 0; i < reps; i++) { + mParcel.setDataPosition(0); + mParcel.writeString16(mValue); + } + } + + public void timeReadString16(int reps) { + mParcel.writeString16(mValue); + + for (int i = 0; i < reps; i++) { + mParcel.setDataPosition(0); + mParcel.readString16(); + } + } +} diff --git a/core/tests/coretests/src/android/os/ParcelTest.java b/core/tests/coretests/src/android/os/ParcelTest.java index 46873b9eb70b..dcb3e2f23da8 100644 --- a/core/tests/coretests/src/android/os/ParcelTest.java +++ b/core/tests/coretests/src/android/os/ParcelTest.java @@ -87,4 +87,27 @@ public class ParcelTest { p.recycle(); } + + /** + * Verify that writing/reading UTF-8 and UTF-16 strings works well. + */ + @Test + public void testStrings() { + final String[] strings = { + null, "", "abc\0def", "com.example.typical_package_name", + "從不喜歡孤單一個 - 蘇永康/吳雨霏", "example" + }; + + final Parcel p = Parcel.obtain(); + for (String string : strings) { + p.writeString8(string); + p.writeString16(string); + } + + p.setDataPosition(0); + for (String string : strings) { + assertEquals(string, p.readString8()); + assertEquals(string, p.readString16()); + } + } } diff --git a/identity/java/android/security/identity/IdentityCredential.java b/identity/java/android/security/identity/IdentityCredential.java index 1db2f6357308..b351b3d77430 100644 --- a/identity/java/android/security/identity/IdentityCredential.java +++ b/identity/java/android/security/identity/IdentityCredential.java @@ -95,9 +95,7 @@ public abstract class IdentityCredential { /** * Sets whether to allow using an authentication key which use count has been exceeded if no * other key is available. This must be called prior to calling - * {@link #getEntries(byte[], Map, byte[], byte[])} or using a - * {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} which references this - * object. + * {@link #getEntries(byte[], Map, byte[], byte[])}. * * By default this is set to true. * @@ -123,13 +121,14 @@ public abstract class IdentityCredential { * entries. * * <p>It is the responsibility of the calling application to know if authentication is needed - * and use e.g. {@link android.hardware.biometrics.BiometricPrompt}) to make the user + * and use e.g. {@link android.hardware.biometrics.BiometricPrompt} to make the user * authenticate using a {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} which * references this object. If needed, this must be done before calling * {@link #getEntries(byte[], Map, byte[], byte[])}. * - * <p>If this method returns successfully (i.e. without throwing an exception), it must not be - * called again on this instance. + * <p>It is permissible to call this method multiple times using the same instance but if this + * is done, the {@code sessionTranscript} parameter must be identical for each call. If this is + * not the case, the {@link SessionTranscriptMismatchException} exception is thrown. * * <p>If not {@code null} the {@code requestMessage} parameter must contain data for the request * from the verifier. The content can be defined in the way appropriate for the credential, byt @@ -141,6 +140,9 @@ public abstract class IdentityCredential { * the example below.</li> * </ul> * + * <p>If these requirements are not met the {@link InvalidRequestMessageException} exception + * is thrown. + * * <p>Here's an example of CBOR which conforms to this requirement: * <pre> * ItemsRequest = { @@ -149,6 +151,8 @@ public abstract class IdentityCredential { * ? "RequestInfo" : {* tstr => any} ; Additional info the reader wants to provide * } * + * DocType = tstr + * * NameSpaces = { * + NameSpace => DataElements ; Requested data elements for each NameSpace * } @@ -172,16 +176,18 @@ public abstract class IdentityCredential { * EReaderKeyBytes * ] * - * DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement) - * EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub) + * DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement) ; Bytes of DeviceEngagement + * EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub) ; Bytes of EReaderKey.pub + * + * EReaderKey.Pub = COSE_Key ; Ephemeral public key provided by reader * </pre> * - * <p>If the SessionTranscript is not empty, a COSE_Key structure for the public part - * of the key-pair previously generated by {@link #createEphemeralKeyPair()} must appear - * somewhere in {@code DeviceEngagement} and the X and Y coordinates must both be present + * <p>where a {@code COSE_Key} structure for the public part of the key-pair previously + * generated by {@link #createEphemeralKeyPair()} must appear somewhere in + * {@code DeviceEngagement} and the X and Y coordinates must both be present * in uncompressed form. * - * <p>If {@code readerAuth} is not {@code null} it must be the bytes of a COSE_Sign1 + * <p>If {@code readerAuth} is not {@code null} it must be the bytes of a {@code COSE_Sign1} * structure as defined in RFC 8152. For the payload nil shall be used and the * detached payload is the ReaderAuthentication CBOR described below. * <pre> @@ -194,20 +200,23 @@ public abstract class IdentityCredential { * ItemsRequestBytes = #6.24(bstr .cbor ItemsRequest) ; Bytes of ItemsRequest * </pre> * - * <p>The public key corresponding to the key used to made signature, can be - * found in the {@code x5chain} unprotected header element of the COSE_Sign1 - * structure (as as described in 'draft-ietf-cose-x509-04'). There will be at - * least one certificate in said element and there may be more (and if so, + * <p>where {@code ItemsRequestBytes} are the bytes in the {@code requestMessage} parameter. + * + * <p>The public key corresponding to the key used to make the signature, can be found in the + * {@code x5chain} unprotected header element of the {@code COSE_Sign1} structure (as as + * described in + * <a href="https://tools.ietf.org/html/draft-ietf-cose-x509-04">draft-ietf-cose-x509-04</a>). + * There will be at least one certificate in said element and there may be more (and if so, * each certificate must be signed by its successor). * - * <p>Data elements protected by reader authentication is returned if, and only if, they are + * <p>Data elements protected by reader authentication are returned if, and only if, they are * mentioned in {@code requestMessage}, {@code requestMessage} is signed by the top-most - * certificate in {@code readerCertificateChain}, and the data element is configured - * with an {@link AccessControlProfile} with a {@link X509Certificate} in - * {@code readerCertificateChain}. + * certificate in the reader's certificate chain, and the data element is configured + * with an {@link AccessControlProfile} configured with an X.509 certificate which appears + * in the certificate chain. * * <p>Note that only items referenced in {@code entriesToRequest} are returned - the - * {@code requestMessage} parameter is only used to for enforcing reader authentication. + * {@code requestMessage} parameter is used only for enforcing reader authentication. * * <p>The reason for having {@code requestMessage} and {@code entriesToRequest} as separate * parameters is that the former represents a request from the remote verifier device @@ -219,13 +228,12 @@ public abstract class IdentityCredential { * @param entriesToRequest The entries to request, organized as a map of namespace * names with each value being a collection of data elements * in the given namespace. - * @param readerSignature COSE_Sign1 structure as described above or {@code null} - * if reader authentication is not being used. + * @param readerSignature A {@code COSE_Sign1} structure as described above or + * {@code null} if reader authentication is not being used. * @return A {@link ResultData} object containing entry data organized by namespace and a * cryptographically authenticated representation of the same data. * @throws SessionTranscriptMismatchException Thrown when trying use multiple different - * session transcripts in the same presentation - * session. + * session transcripts. * @throws NoAuthenticationKeyAvailableException if authentication keys were never * provisioned, the method * {@link #setAvailableAuthenticationKeys(int, int)} @@ -255,8 +263,8 @@ public abstract class IdentityCredential { * Sets the number of dynamic authentication keys the {@code IdentityCredential} will maintain, * and the number of times each should be used. * - * <p>{@code IdentityCredential}s will select the least-used dynamic authentication key each - * time {@link #getEntries(byte[], Map, byte[], byte[])} is called. {@code IdentityCredential}s + * <p>The Identity Credential system will select the least-used dynamic authentication key each + * time {@link #getEntries(byte[], Map, byte[], byte[])} is called. Identity Credentials * for which this method has not been called behave as though it had been called wit * {@code keyCount} 0 and {@code maxUsesPerKey} 1. * @@ -274,9 +282,10 @@ public abstract class IdentityCredential { * <p>When there aren't enough certified dynamic authentication keys, either because the key * count has been increased or because one or more keys have reached their usage count, this * method will generate replacement keys and certificates and return them for issuer - * certification. The issuer certificates and associated static authentication data must then - * be provided back to the {@code IdentityCredential} using - * {@link #storeStaticAuthenticationData(X509Certificate, byte[])}. + * certification. The issuer certificates and associated static authentication data must then + * be provided back to the Identity Credential using + * {@link #storeStaticAuthenticationData(X509Certificate, byte[])}. The private part of + * each authentication key never leaves secure hardware. * * <p>Each X.509 certificate is signed by CredentialKey. The certificate chain for CredentialKey * can be obtained using the {@link #getCredentialKeyCertificateChain()} method. diff --git a/identity/java/android/security/identity/IdentityCredentialStore.java b/identity/java/android/security/identity/IdentityCredentialStore.java index a1dfc77adb29..4f834d2b87b5 100644 --- a/identity/java/android/security/identity/IdentityCredentialStore.java +++ b/identity/java/android/security/identity/IdentityCredentialStore.java @@ -78,17 +78,21 @@ public abstract class IdentityCredentialStore { /** * Specifies that the cipher suite that will be used to secure communications between the reader - * is: + * and the prover is using the following primitives * * <ul> - * <li>ECDHE with HKDF-SHA-256 for key agreement.</li> - * <li>AES-256 with GCM block mode for authenticated encryption (nonces are incremented by one - * for every message).</li> - * <li>ECDSA with SHA-256 for signing (used for signing session transcripts to defeat - * man-in-the-middle attacks), signing keys are not ephemeral. See {@link IdentityCredential} - * for details on reader and prover signing keys.</li> + * <li>ECKA-DH (Elliptic Curve Key Agreement Algorithm - Diffie-Hellman, see BSI TR-03111).</li> + * + * <li>HKDF-SHA-256 (see RFC 5869).</li> + * + * <li>AES-256-GCM (see NIST SP 800-38D).</li> + * + * <li>HMAC-SHA-256 (see RFC 2104).</li> * </ul> * + * <p>The exact way these primitives are combined to derive the session key is specified in + * section 9.2.1.4 of ISO/IEC 18013-5 (see description of cipher suite '1').<p> + * * <p> * At present this is the only supported cipher suite. */ @@ -135,9 +139,20 @@ public abstract class IdentityCredentialStore { /** * Creates a new credential. * + * <p>When a credential is created, a cryptographic key-pair - CredentialKey - is created which + * is used to authenticate the store to the Issuing Authority. The private part of this + * key-pair never leaves secure hardware and the public part can be obtained using + * {@link WritableIdentityCredential#getCredentialKeyCertificateChain(byte[])} on the + * returned object. + * + * <p>In addition, all of the Credential data content is imported and a certificate for the + * CredentialKey and a signature produced with the CredentialKey are created. These latter + * values may be checked by an issuing authority to verify that the data was imported into + * secure hardware and that it was imported unmodified. + * * @param credentialName The name used to identify the credential. * @param docType The document type for the credential. - * @return A @{link WritableIdentityCredential} that can be used to create a new credential. + * @return A {@link WritableIdentityCredential} that can be used to create a new credential. * @throws AlreadyPersonalizedException if a credential with the given name already exists. * @throws DocTypeNotSupportedException if the given document type isn't supported by the store. */ @@ -148,6 +163,10 @@ public abstract class IdentityCredentialStore { /** * Retrieve a named credential. * + * <p>The cipher suite used to communicate with the remote verifier must also be specified. + * Currently only a single cipher-suite is supported. Support for other cipher suites may be + * added in a future version of this API. + * * @param credentialName the name of the credential to retrieve. * @param cipherSuite the cipher suite to use for communicating with the verifier. * @return The named credential, or null if not found. diff --git a/identity/java/android/security/identity/ResultData.java b/identity/java/android/security/identity/ResultData.java index 13552d619e05..37de2c4a50ea 100644 --- a/identity/java/android/security/identity/ResultData.java +++ b/identity/java/android/security/identity/ResultData.java @@ -34,23 +34,23 @@ public abstract class ResultData { /** Value was successfully retrieved. */ public static final int STATUS_OK = 0; - /** Requested entry does not exist. */ + /** The entry does not exist. */ public static final int STATUS_NO_SUCH_ENTRY = 1; - /** Requested entry was not requested. */ + /** The entry was not requested. */ public static final int STATUS_NOT_REQUESTED = 2; - /** Requested entry wasn't in the request message. */ + /** The entry wasn't in the request message. */ public static final int STATUS_NOT_IN_REQUEST_MESSAGE = 3; - /** The requested entry was not retrieved because user authentication wasn't performed. */ + /** The entry was not retrieved because user authentication failed. */ public static final int STATUS_USER_AUTHENTICATION_FAILED = 4; - /** The requested entry was not retrieved because reader authentication wasn't performed. */ + /** The entry was not retrieved because reader authentication failed. */ public static final int STATUS_READER_AUTHENTICATION_FAILED = 5; /** - * The requested entry was not retrieved because it was configured without any access + * The entry was not retrieved because it was configured without any access * control profile. */ public static final int STATUS_NO_ACCESS_CONTROL_PROFILES = 6; @@ -88,11 +88,10 @@ public abstract class ResultData { * * DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement) * EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub) - * * DeviceNameSpacesBytes = #6.24(bstr .cbor DeviceNameSpaces) * </pre> * - * where + * <p>where * * <pre> * DeviceNameSpaces = { @@ -116,15 +115,16 @@ public abstract class ResultData { public abstract @NonNull byte[] getAuthenticatedData(); /** - * Returns a message authentication code over the data returned by - * {@link #getAuthenticatedData}, to prove to the reader that the data is from a trusted - * credential. + * Returns a message authentication code over the {@code DeviceAuthentication} CBOR + * specified in {@link #getAuthenticatedData()}, to prove to the reader that the data + * is from a trusted credential. * * <p>The MAC proves to the reader that the data is from a trusted credential. This code is * produced by using the key agreement and key derivation function from the ciphersuite * with the authentication private key and the reader ephemeral public key to compute a * shared message authentication code (MAC) key, then using the MAC function from the - * ciphersuite to compute a MAC of the authenticated data. + * ciphersuite to compute a MAC of the authenticated data. See section 9.2.3.5 of + * ISO/IEC 18013-5 for details of this operation. * * <p>If the {@code sessionTranscript} parameter passed to * {@link IdentityCredential#getEntries(byte[], Map, byte[], byte[])} was {@code null} @@ -157,7 +157,7 @@ public abstract class ResultData { /** * Get the names of all entries. * - * This includes the name of entries that wasn't successfully retrieved. + * <p>This includes the name of entries that wasn't successfully retrieved. * * @param namespaceName the namespace name to get entries for. * @return A collection of names or {@code null} if there are no entries for the given @@ -168,7 +168,7 @@ public abstract class ResultData { /** * Get the names of all entries that was successfully retrieved. * - * This only return entries for which {@link #getStatus(String, String)} will return + * <p>This only return entries for which {@link #getStatus(String, String)} will return * {@link #STATUS_OK}. * * @param namespaceName the namespace name to get entries for. @@ -181,16 +181,15 @@ public abstract class ResultData { /** * Gets the status of an entry. * - * This returns {@link #STATUS_OK} if the value was retrieved, {@link #STATUS_NO_SUCH_ENTRY} + * <p>This returns {@link #STATUS_OK} if the value was retrieved, {@link #STATUS_NO_SUCH_ENTRY} * if the given entry wasn't retrieved, {@link #STATUS_NOT_REQUESTED} if it wasn't requested, * {@link #STATUS_NOT_IN_REQUEST_MESSAGE} if the request message was set but the entry wasn't - * present in the request message, - * {@link #STATUS_USER_AUTHENTICATION_FAILED} if the value + * present in the request message, {@link #STATUS_USER_AUTHENTICATION_FAILED} if the value * wasn't retrieved because the necessary user authentication wasn't performed, - * {@link #STATUS_READER_AUTHENTICATION_FAILED} if the supplied reader certificate chain - * didn't match the set of certificates the entry was provisioned with, or - * {@link #STATUS_NO_ACCESS_CONTROL_PROFILES} if the entry was configured without any - * access control profiles. + * {@link #STATUS_READER_AUTHENTICATION_FAILED} if the supplied reader certificate chain didn't + * match the set of certificates the entry was provisioned with, or + * {@link #STATUS_NO_ACCESS_CONTROL_PROFILES} if the entry was configured without any access + * control profiles. * * @param namespaceName the namespace name of the entry. * @param name the name of the entry to get the value for. @@ -201,7 +200,7 @@ public abstract class ResultData { /** * Gets the raw CBOR data for the value of an entry. * - * This should only be called on an entry for which the {@link #getStatus(String, String)} + * <p>This should only be called on an entry for which the {@link #getStatus(String, String)} * method returns {@link #STATUS_OK}. * * @param namespaceName the namespace name of the entry. diff --git a/identity/java/android/security/identity/WritableIdentityCredential.java b/identity/java/android/security/identity/WritableIdentityCredential.java index e2a389bfd4da..c7aa32855abc 100644 --- a/identity/java/android/security/identity/WritableIdentityCredential.java +++ b/identity/java/android/security/identity/WritableIdentityCredential.java @@ -41,15 +41,16 @@ public abstract class WritableIdentityCredential { * <a href="https://source.android.com/security/keystore/attestation">Android Keystore</a> * attestation extension which describes the key and the security hardware in which it lives. * - * <p>Additionally, the attestation extension will contain the tag TODO_IC_KEY which indicates - * it is an Identity Credential key (which can only sign/MAC very specific messages) and not - * an Android Keystore key (which can be used to sign/MAC anything). + * <p>Additionally, the attestation extension will contain the tag Tag::IDENTITY_CREDENTIAL_KEY + * which indicates it is an Identity Credential key (which can only sign/MAC very specific + * messages) and not an Android Keystore key (which can be used to sign/MAC anything). * * <p>The issuer <b>MUST</b> carefully examine this certificate chain including (but not - * limited to) checking that the root certificate is well-known, the tag TODO_IC_KEY is - * present, the passed in challenge is present, the device has verified boot enabled, that each - * certificate in the chain is signed by its successor, that none of the certificates have been - * revoked and so on. + * limited to) checking that the root certificate is well-known, the tag + * Tag::IDENTITY_CREDENTIAL_KEY present, the passed in challenge is present, the tag + * Tag::ATTESTATION_APPLICATION_ID is set to the expected Android application, the device + * has verified boot enabled, each certificate in the chain is signed by its successor, + * none of the certificates have been revoked, and so on. * * <p>It is not strictly necessary to use this method to provision a credential if the issuing * authority doesn't care about the nature of the security hardware. If called, however, this diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 3e1f72da8731..8ea68833e20d 100755 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -2713,6 +2713,32 @@ public class AudioManager { } /** + * @hide + */ + public static String audioFocusToString(int focus) { + switch (focus) { + case AUDIOFOCUS_NONE: + return "AUDIOFOCUS_NONE"; + case AUDIOFOCUS_GAIN: + return "AUDIOFOCUS_GAIN"; + case AUDIOFOCUS_GAIN_TRANSIENT: + return "AUDIOFOCUS_GAIN_TRANSIENT"; + case AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: + return "AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK"; + case AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: + return "AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE"; + case AUDIOFOCUS_LOSS: + return "AUDIOFOCUS_LOSS"; + case AUDIOFOCUS_LOSS_TRANSIENT: + return "AUDIOFOCUS_LOSS_TRANSIENT"; + case AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // Note CAN_DUCK not MAY_DUCK. + return "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK"; + default: + return "AUDIO_FOCUS_UNKNOWN(" + focus + ")"; + } + } + + /** * Used to indicate no audio focus has been gained or lost, or requested. */ public static final int AUDIOFOCUS_NONE = 0; diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index c11762bcdb40..373f6e126924 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -214,6 +214,175 @@ public class AudioSystem } } + /** + * @hide + * Convert a native audio format integer constant to a string. + */ + public static String audioFormatToString(int audioFormat) { + switch (audioFormat) { + case /* AUDIO_FORMAT_INVALID */ 0xFFFFFFFF: + return "AUDIO_FORMAT_INVALID"; + case /* AUDIO_FORMAT_DEFAULT */ 0: + return "AUDIO_FORMAT_DEFAULT"; + case /* AUDIO_FORMAT_MP3 */ 0x01000000: + return "AUDIO_FORMAT_MP3"; + case /* AUDIO_FORMAT_AMR_NB */ 0x02000000: + return "AUDIO_FORMAT_AMR_NB"; + case /* AUDIO_FORMAT_AMR_WB */ 0x03000000: + return "AUDIO_FORMAT_AMR_WB"; + case /* AUDIO_FORMAT_AAC */ 0x04000000: + return "AUDIO_FORMAT_AAC"; + case /* AUDIO_FORMAT_HE_AAC_V1 */ 0x05000000: + return "AUDIO_FORMAT_HE_AAC_V1"; + case /* AUDIO_FORMAT_HE_AAC_V2 */ 0x06000000: + return "AUDIO_FORMAT_HE_AAC_V2"; + case /* AUDIO_FORMAT_VORBIS */ 0x07000000: + return "AUDIO_FORMAT_VORBIS"; + case /* AUDIO_FORMAT_OPUS */ 0x08000000: + return "AUDIO_FORMAT_OPUS"; + case /* AUDIO_FORMAT_AC3 */ 0x09000000: + return "AUDIO_FORMAT_AC3"; + case /* AUDIO_FORMAT_E_AC3 */ 0x0A000000: + return "AUDIO_FORMAT_E_AC3"; + case /* AUDIO_FORMAT_DTS */ 0x0B000000: + return "AUDIO_FORMAT_DTS"; + case /* AUDIO_FORMAT_DTS_HD */ 0x0C000000: + return "AUDIO_FORMAT_DTS_HD"; + case /* AUDIO_FORMAT_IEC61937 */ 0x0D000000: + return "AUDIO_FORMAT_IEC61937"; + case /* AUDIO_FORMAT_DOLBY_TRUEHD */ 0x0E000000: + return "AUDIO_FORMAT_DOLBY_TRUEHD"; + case /* AUDIO_FORMAT_EVRC */ 0x10000000: + return "AUDIO_FORMAT_EVRC"; + case /* AUDIO_FORMAT_EVRCB */ 0x11000000: + return "AUDIO_FORMAT_EVRCB"; + case /* AUDIO_FORMAT_EVRCWB */ 0x12000000: + return "AUDIO_FORMAT_EVRCWB"; + case /* AUDIO_FORMAT_EVRCNW */ 0x13000000: + return "AUDIO_FORMAT_EVRCNW"; + case /* AUDIO_FORMAT_AAC_ADIF */ 0x14000000: + return "AUDIO_FORMAT_AAC_ADIF"; + case /* AUDIO_FORMAT_WMA */ 0x15000000: + return "AUDIO_FORMAT_WMA"; + case /* AUDIO_FORMAT_WMA_PRO */ 0x16000000: + return "AUDIO_FORMAT_WMA_PRO"; + case /* AUDIO_FORMAT_AMR_WB_PLUS */ 0x17000000: + return "AUDIO_FORMAT_AMR_WB_PLUS"; + case /* AUDIO_FORMAT_MP2 */ 0x18000000: + return "AUDIO_FORMAT_MP2"; + case /* AUDIO_FORMAT_QCELP */ 0x19000000: + return "AUDIO_FORMAT_QCELP"; + case /* AUDIO_FORMAT_DSD */ 0x1A000000: + return "AUDIO_FORMAT_DSD"; + case /* AUDIO_FORMAT_FLAC */ 0x1B000000: + return "AUDIO_FORMAT_FLAC"; + case /* AUDIO_FORMAT_ALAC */ 0x1C000000: + return "AUDIO_FORMAT_ALAC"; + case /* AUDIO_FORMAT_APE */ 0x1D000000: + return "AUDIO_FORMAT_APE"; + case /* AUDIO_FORMAT_AAC_ADTS */ 0x1E000000: + return "AUDIO_FORMAT_AAC_ADTS"; + case /* AUDIO_FORMAT_SBC */ 0x1F000000: + return "AUDIO_FORMAT_SBC"; + case /* AUDIO_FORMAT_APTX */ 0x20000000: + return "AUDIO_FORMAT_APTX"; + case /* AUDIO_FORMAT_APTX_HD */ 0x21000000: + return "AUDIO_FORMAT_APTX_HD"; + case /* AUDIO_FORMAT_AC4 */ 0x22000000: + return "AUDIO_FORMAT_AC4"; + case /* AUDIO_FORMAT_LDAC */ 0x23000000: + return "AUDIO_FORMAT_LDAC"; + case /* AUDIO_FORMAT_MAT */ 0x24000000: + return "AUDIO_FORMAT_MAT"; + case /* AUDIO_FORMAT_AAC_LATM */ 0x25000000: + return "AUDIO_FORMAT_AAC_LATM"; + case /* AUDIO_FORMAT_CELT */ 0x26000000: + return "AUDIO_FORMAT_CELT"; + case /* AUDIO_FORMAT_APTX_ADAPTIVE */ 0x27000000: + return "AUDIO_FORMAT_APTX_ADAPTIVE"; + case /* AUDIO_FORMAT_LHDC */ 0x28000000: + return "AUDIO_FORMAT_LHDC"; + case /* AUDIO_FORMAT_LHDC_LL */ 0x29000000: + return "AUDIO_FORMAT_LHDC_LL"; + case /* AUDIO_FORMAT_APTX_TWSP */ 0x2A000000: + return "AUDIO_FORMAT_APTX_TWSP"; + + /* Aliases */ + case /* AUDIO_FORMAT_PCM_16_BIT */ 0x1: + return "AUDIO_FORMAT_PCM_16_BIT"; // (PCM | PCM_SUB_16_BIT) + case /* AUDIO_FORMAT_PCM_8_BIT */ 0x2: + return "AUDIO_FORMAT_PCM_8_BIT"; // (PCM | PCM_SUB_8_BIT) + case /* AUDIO_FORMAT_PCM_32_BIT */ 0x3: + return "AUDIO_FORMAT_PCM_32_BIT"; // (PCM | PCM_SUB_32_BIT) + case /* AUDIO_FORMAT_PCM_8_24_BIT */ 0x4: + return "AUDIO_FORMAT_PCM_8_24_BIT"; // (PCM | PCM_SUB_8_24_BIT) + case /* AUDIO_FORMAT_PCM_FLOAT */ 0x5: + return "AUDIO_FORMAT_PCM_FLOAT"; // (PCM | PCM_SUB_FLOAT) + case /* AUDIO_FORMAT_PCM_24_BIT_PACKED */ 0x6: + return "AUDIO_FORMAT_PCM_24_BIT_PACKED"; // (PCM | PCM_SUB_24_BIT_PACKED) + case /* AUDIO_FORMAT_AAC_MAIN */ 0x4000001: + return "AUDIO_FORMAT_AAC_MAIN"; // (AAC | AAC_SUB_MAIN) + case /* AUDIO_FORMAT_AAC_LC */ 0x4000002: + return "AUDIO_FORMAT_AAC_LC"; // (AAC | AAC_SUB_LC) + case /* AUDIO_FORMAT_AAC_SSR */ 0x4000004: + return "AUDIO_FORMAT_AAC_SSR"; // (AAC | AAC_SUB_SSR) + case /* AUDIO_FORMAT_AAC_LTP */ 0x4000008: + return "AUDIO_FORMAT_AAC_LTP"; // (AAC | AAC_SUB_LTP) + case /* AUDIO_FORMAT_AAC_HE_V1 */ 0x4000010: + return "AUDIO_FORMAT_AAC_HE_V1"; // (AAC | AAC_SUB_HE_V1) + case /* AUDIO_FORMAT_AAC_SCALABLE */ 0x4000020: + return "AUDIO_FORMAT_AAC_SCALABLE"; // (AAC | AAC_SUB_SCALABLE) + case /* AUDIO_FORMAT_AAC_ERLC */ 0x4000040: + return "AUDIO_FORMAT_AAC_ERLC"; // (AAC | AAC_SUB_ERLC) + case /* AUDIO_FORMAT_AAC_LD */ 0x4000080: + return "AUDIO_FORMAT_AAC_LD"; // (AAC | AAC_SUB_LD) + case /* AUDIO_FORMAT_AAC_HE_V2 */ 0x4000100: + return "AUDIO_FORMAT_AAC_HE_V2"; // (AAC | AAC_SUB_HE_V2) + case /* AUDIO_FORMAT_AAC_ELD */ 0x4000200: + return "AUDIO_FORMAT_AAC_ELD"; // (AAC | AAC_SUB_ELD) + case /* AUDIO_FORMAT_AAC_XHE */ 0x4000300: + return "AUDIO_FORMAT_AAC_XHE"; // (AAC | AAC_SUB_XHE) + case /* AUDIO_FORMAT_AAC_ADTS_MAIN */ 0x1e000001: + return "AUDIO_FORMAT_AAC_ADTS_MAIN"; // (AAC_ADTS | AAC_SUB_MAIN) + case /* AUDIO_FORMAT_AAC_ADTS_LC */ 0x1e000002: + return "AUDIO_FORMAT_AAC_ADTS_LC"; // (AAC_ADTS | AAC_SUB_LC) + case /* AUDIO_FORMAT_AAC_ADTS_SSR */ 0x1e000004: + return "AUDIO_FORMAT_AAC_ADTS_SSR"; // (AAC_ADTS | AAC_SUB_SSR) + case /* AUDIO_FORMAT_AAC_ADTS_LTP */ 0x1e000008: + return "AUDIO_FORMAT_AAC_ADTS_LTP"; // (AAC_ADTS | AAC_SUB_LTP) + case /* AUDIO_FORMAT_AAC_ADTS_HE_V1 */ 0x1e000010: + return "AUDIO_FORMAT_AAC_ADTS_HE_V1"; // (AAC_ADTS | AAC_SUB_HE_V1) + case /* AUDIO_FORMAT_AAC_ADTS_SCALABLE */ 0x1e000020: + return "AUDIO_FORMAT_AAC_ADTS_SCALABLE"; // (AAC_ADTS | AAC_SUB_SCALABLE) + case /* AUDIO_FORMAT_AAC_ADTS_ERLC */ 0x1e000040: + return "AUDIO_FORMAT_AAC_ADTS_ERLC"; // (AAC_ADTS | AAC_SUB_ERLC) + case /* AUDIO_FORMAT_AAC_ADTS_LD */ 0x1e000080: + return "AUDIO_FORMAT_AAC_ADTS_LD"; // (AAC_ADTS | AAC_SUB_LD) + case /* AUDIO_FORMAT_AAC_ADTS_HE_V2 */ 0x1e000100: + return "AUDIO_FORMAT_AAC_ADTS_HE_V2"; // (AAC_ADTS | AAC_SUB_HE_V2) + case /* AUDIO_FORMAT_AAC_ADTS_ELD */ 0x1e000200: + return "AUDIO_FORMAT_AAC_ADTS_ELD"; // (AAC_ADTS | AAC_SUB_ELD) + case /* AUDIO_FORMAT_AAC_ADTS_XHE */ 0x1e000300: + return "AUDIO_FORMAT_AAC_ADTS_XHE"; // (AAC_ADTS | AAC_SUB_XHE) + case /* AUDIO_FORMAT_AAC_LATM_LC */ 0x25000002: + return "AUDIO_FORMAT_AAC_LATM_LC"; // (AAC_LATM | AAC_SUB_LC) + case /* AUDIO_FORMAT_AAC_LATM_HE_V1 */ 0x25000010: + return "AUDIO_FORMAT_AAC_LATM_HE_V1"; // (AAC_LATM | AAC_SUB_HE_V1) + case /* AUDIO_FORMAT_AAC_LATM_HE_V2 */ 0x25000100: + return "AUDIO_FORMAT_AAC_LATM_HE_V2"; // (AAC_LATM | AAC_SUB_HE_V2) + case /* AUDIO_FORMAT_E_AC3_JOC */ 0xA000001: + return "AUDIO_FORMAT_E_AC3_JOC"; // (E_AC3 | E_AC3_SUB_JOC) + case /* AUDIO_FORMAT_MAT_1_0 */ 0x24000001: + return "AUDIO_FORMAT_MAT_1_0"; // (MAT | MAT_SUB_1_0) + case /* AUDIO_FORMAT_MAT_2_0 */ 0x24000002: + return "AUDIO_FORMAT_MAT_2_0"; // (MAT | MAT_SUB_2_0) + case /* AUDIO_FORMAT_MAT_2_1 */ 0x24000003: + return "AUDIO_FORMAT_MAT_2_1"; // (MAT | MAT_SUB_2_1) + default: + return "AUDIO_FORMAT_(" + audioFormat + ")"; + } + } + /* Routing bits for the former setRouting/getRouting API */ /** @hide @deprecated */ @Deprecated public static final int ROUTE_EARPIECE = (1 << 0); diff --git a/media/java/android/media/MediaMetrics.java b/media/java/android/media/MediaMetrics.java index 540955f3b393..f6f482dd0cd3 100644 --- a/media/java/android/media/MediaMetrics.java +++ b/media/java/android/media/MediaMetrics.java @@ -38,6 +38,117 @@ import java.util.Objects; public class MediaMetrics { public static final String TAG = "MediaMetrics"; + public static final String SEPARATOR = "."; + + /** + * A list of established MediaMetrics names that can be used for Items. + */ + public static class Name { + public static final String AUDIO = "audio"; + public static final String AUDIO_BLUETOOTH = AUDIO + SEPARATOR + "bluetooth"; + public static final String AUDIO_DEVICE = AUDIO + SEPARATOR + "device"; + public static final String AUDIO_FOCUS = AUDIO + SEPARATOR + "focus"; + public static final String AUDIO_FORCE_USE = AUDIO + SEPARATOR + "forceUse"; + public static final String AUDIO_MIC = AUDIO + SEPARATOR + "mic"; + public static final String AUDIO_SERVICE = AUDIO + SEPARATOR + "service"; + public static final String AUDIO_VOLUME = AUDIO + SEPARATOR + "volume"; + public static final String AUDIO_VOLUME_EVENT = AUDIO_VOLUME + SEPARATOR + "event"; + } + + /** + * A list of established string values. + */ + public static class Value { + public static final String CONNECT = "connect"; + public static final String CONNECTED = "connected"; + public static final String DISCONNECT = "disconnect"; + public static final String DISCONNECTED = "disconnected"; + public static final String DOWN = "down"; + public static final String MUTE = "mute"; + public static final String NO = "no"; + public static final String OFF = "off"; + public static final String ON = "on"; + public static final String UNMUTE = "unmute"; + public static final String UP = "up"; + public static final String YES = "yes"; + } + + /** + * A list of standard property keys for consistent use and type. + */ + public static class Property { + // A use for Bluetooth or USB device addresses + public static final Key<String> ADDRESS = createKey("address", String.class); + // A string representing the Audio Attributes + public static final Key<String> ATTRIBUTES = createKey("attributes", String.class); + + // The calling package responsible for the state change + public static final Key<String> CALLING_PACKAGE = + createKey("callingPackage", String.class); + + // The client name + public static final Key<String> CLIENT_NAME = createKey("clientName", String.class); + + // The device type + public static final Key<Integer> DELAY_MS = createKey("delayMs", Integer.class); + + // The device type + public static final Key<String> DEVICE = createKey("device", String.class); + + // For volume changes, up or down + public static final Key<String> DIRECTION = createKey("direction", String.class); + + // A reason for early return or error + public static final Key<String> EARLY_RETURN = + createKey("earlyReturn", String.class); + // ENCODING_ ... string to match AudioFormat encoding + public static final Key<String> ENCODING = createKey("encoding", String.class); + + public static final Key<String> EVENT = createKey("event#", String.class); + + // event generated is external (yes, no) + public static final Key<String> EXTERNAL = createKey("external", String.class); + + public static final Key<Integer> FLAGS = createKey("flags", Integer.class); + public static final Key<String> FOCUS_CHANGE_HINT = + createKey("focusChangeHint", String.class); + public static final Key<String> FORCE_USE_DUE_TO = + createKey("forceUseDueTo", String.class); + public static final Key<String> FORCE_USE_MODE = + createKey("forceUseMode", String.class); + public static final Key<Double> GAIN_DB = + createKey("gainDb", Double.class); + public static final Key<String> GROUP = + createKey("group", String.class); + // For volume + public static final Key<Integer> INDEX = createKey("index", Integer.class); + public static final Key<Integer> MAX_INDEX = createKey("maxIndex", Integer.class); + public static final Key<Integer> MIN_INDEX = createKey("minIndex", Integer.class); + public static final Key<String> MODE = + createKey("mode", String.class); // audio_mode + public static final Key<String> MUTE = + createKey("mute", String.class); // microphone, on or off. + + // Bluetooth or Usb device name + public static final Key<String> NAME = + createKey("name", String.class); + + // Number of observers + public static final Key<Integer> OBSERVERS = + createKey("observers", Integer.class); + + public static final Key<String> REQUEST = + createKey("request", String.class); + + // For Bluetooth + public static final Key<String> SCO_AUDIO_MODE = + createKey("scoAudioMode", String.class); + public static final Key<Integer> SDK = createKey("sdk", Integer.class); + public static final Key<String> STATE = createKey("state", String.class); + public static final Key<Integer> STATUS = createKey("status", Integer.class); + public static final Key<String> STREAM_TYPE = createKey("streamType", String.class); + } + /** * The TYPE constants below should match those in native MediaMetricsItem.h */ diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java index 0ea962493164..2c65cc4440a4 100644 --- a/media/java/android/media/MediaRouter2.java +++ b/media/java/android/media/MediaRouter2.java @@ -35,7 +35,6 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -379,11 +378,7 @@ public final class MediaRouter2 { */ public void transferTo(@NonNull MediaRoute2Info route) { Objects.requireNonNull(route, "route must not be null"); - - List<RoutingController> controllers = getControllers(); - RoutingController controller = controllers.get(controllers.size() - 1); - - transfer(controller, route); + transfer(getCurrentController(), route); } /** @@ -391,10 +386,7 @@ public final class MediaRouter2 { * controls the media routing, this method is a no-op. */ public void stop() { - List<RoutingController> controllers = getControllers(); - RoutingController controller = controllers.get(controllers.size() - 1); - - controller.release(); + getCurrentController().release(); } /** @@ -417,12 +409,9 @@ public final class MediaRouter2 { return; } - controller.release(); - final int requestId = mControllerCreationRequestCnt.getAndIncrement(); - ControllerCreationRequest request = - new ControllerCreationRequest(requestId, controller, route); + ControllerCreationRequest request = new ControllerCreationRequest(requestId, route); mControllerCreationRequests.add(request); OnGetControllerHintsListener listener = mOnGetControllerHintsListener; @@ -450,6 +439,12 @@ public final class MediaRouter2 { } } + @NonNull + private RoutingController getCurrentController() { + List<RoutingController> controllers = getControllers(); + return controllers.get(controllers.size() - 1); + } + /** * Gets a {@link RoutingController} which can control the routes provided by system. * e.g. Phone speaker, wired headset, Bluetooth, etc. @@ -474,13 +469,8 @@ public final class MediaRouter2 { public List<RoutingController> getControllers() { List<RoutingController> result = new ArrayList<>(); result.add(0, mSystemController); - - Collection<RoutingController> controllers; synchronized (sRouterLock) { - controllers = mRoutingControllers.values(); - if (controllers != null) { - result.addAll(controllers); - } + result.addAll(mRoutingControllers.values()); } return result; } @@ -608,19 +598,33 @@ public final class MediaRouter2 { } } - if (sessionInfo != null) { - RoutingController newController; - if (sessionInfo.isSystemSession()) { - newController = getSystemController(); - } else { - newController = new RoutingController(sessionInfo); - synchronized (sRouterLock) { - mRoutingControllers.put(newController.getId(), newController); - } + if (sessionInfo == null) { + return; + } + + RoutingController oldController = getCurrentController(); + if (!oldController.releaseInternal( + /* shouldReleaseSession= */ true, /* shouldNotifyStop= */ false)) { + // Could not release the controller since it was just released by other thread. + oldController = getSystemController(); + } + + RoutingController newController; + if (sessionInfo.isSystemSession()) { + newController = getSystemController(); + newController.setRoutingSessionInfo(sessionInfo); + } else { + newController = new RoutingController(sessionInfo); + synchronized (sRouterLock) { + mRoutingControllers.put(newController.getId(), newController); } - //TODO: Determine oldController properly when transfer is launched by Output Switcher. - notifyTransfer(matchingRequest != null ? matchingRequest.mController : - getSystemController(), newController); + } + + // Two controller can be same if stop() is called before the result of Cast -> Phone comes. + if (oldController != newController) { + notifyTransfer(oldController, newController); + } else if (matchingRequest != null) { + notifyTransferFailure(matchingRequest.mRoute); } } @@ -687,7 +691,8 @@ public final class MediaRouter2 { return; } - matchingController.releaseInternal(/* shouldReleaseSession= */ false); + matchingController.releaseInternal( + /* shouldReleaseSession= */ false, /* shouldNotifyStop= */ true); } void onGetControllerHintsForCreatingSessionOnHandler(long uniqueRequestId, @@ -814,8 +819,9 @@ public final class MediaRouter2 { public abstract static class TransferCallback { /** * Called when a media is transferred between two different routing controllers. - * This can happen by calling {@link #transferTo(MediaRoute2Info)} or - * {@link RoutingController#release()}. + * This can happen by calling {@link #transferTo(MediaRoute2Info)}. + * The {@code oldController} is released before this method is called, except for the + * {@link #getSystemController() system controller}. * * @param oldController the previous controller that controlled routing * @param newController the new controller to control routing @@ -833,6 +839,9 @@ public final class MediaRouter2 { /** * Called when a media routing stops. It can be stopped by a user or a provider. + * App should not continue playing media locally when this method is called. + * The {@code oldController} is released before this method is called, except for the + * {@link #getSystemController() system controller}. * * @param controller the controller that controlled the stopped media routing. */ @@ -1206,14 +1215,18 @@ public final class MediaRouter2 { */ // TODO: Add tests using {@link MediaRouter2Manager#getActiveSessions()}. public void release() { - releaseInternal(/* shouldReleaseSession= */ true); + releaseInternal(/* shouldReleaseSession= */ true, /* shouldNotifyStop= */ true); } - void releaseInternal(boolean shouldReleaseSession) { + /** + * Returns {@code true} when succeeded to release, {@code false} if the controller is + * already released. + */ + boolean releaseInternal(boolean shouldReleaseSession, boolean shouldNotifyStop) { synchronized (mControllerLock) { if (mIsReleased) { Log.w(TAG, "releaseInternal() called on released controller. Ignoring."); - return; + return false; } mIsReleased = true; } @@ -1232,12 +1245,11 @@ public final class MediaRouter2 { } } - if (Thread.currentThread() == mHandler.getLooper().getThread()) { - notifyStop(this); - } else { + if (shouldNotifyStop) { mHandler.sendMessage(obtainMessage(MediaRouter2::notifyStop, MediaRouter2.this, RoutingController.this)); } + return true; } @Override @@ -1294,13 +1306,14 @@ public final class MediaRouter2 { } @Override - public void release() { - // Do nothing. SystemRoutingController will never be released + public boolean isReleased() { + // SystemRoutingController will never be released + return false; } @Override - public boolean isReleased() { - // SystemRoutingController will never be released + boolean releaseInternal(boolean shouldReleaseSession, boolean shouldNotifyStop) { + // Do nothing. SystemRoutingController will never be released return false; } } @@ -1391,13 +1404,10 @@ public final class MediaRouter2 { static final class ControllerCreationRequest { public final int mRequestId; - public final RoutingController mController; public final MediaRoute2Info mRoute; - ControllerCreationRequest(int requestId, @NonNull RoutingController controller, - @NonNull MediaRoute2Info route) { + ControllerCreationRequest(int requestId, @NonNull MediaRoute2Info route) { mRequestId = requestId; - mController = controller; mRoute = route; } } diff --git a/media/java/android/media/RoutingSessionInfo.java b/media/java/android/media/RoutingSessionInfo.java index 629cf1544bd1..608e29a7a6ca 100644 --- a/media/java/android/media/RoutingSessionInfo.java +++ b/media/java/android/media/RoutingSessionInfo.java @@ -310,19 +310,19 @@ public final class RoutingSessionInfo implements Parcelable { public String toString() { StringBuilder result = new StringBuilder() .append("RoutingSessionInfo{ ") - .append("sessionId=").append(mId) - .append(", name=").append(mName) + .append("sessionId=").append(getId()) + .append(", name=").append(getName()) .append(", selectedRoutes={") - .append(String.join(",", mSelectedRoutes)) + .append(String.join(",", getSelectedRoutes())) .append("}") .append(", selectableRoutes={") - .append(String.join(",", mSelectableRoutes)) + .append(String.join(",", getSelectableRoutes())) .append("}") .append(", deselectableRoutes={") - .append(String.join(",", mDeselectableRoutes)) + .append(String.join(",", getDeselectableRoutes())) .append("}") .append(", transferableRoutes={") - .append(String.join(",", mTransferableRoutes)) + .append(String.join(",", getTransferableRoutes())) .append("}") .append(", volumeHandling=").append(getVolumeHandling()) .append(", volumeMax=").append(getVolumeMax()) diff --git a/media/java/android/media/soundtrigger_middleware/OWNERS b/media/java/android/media/soundtrigger_middleware/OWNERS new file mode 100644 index 000000000000..e5d037003ac4 --- /dev/null +++ b/media/java/android/media/soundtrigger_middleware/OWNERS @@ -0,0 +1,2 @@ +ytai@google.com +elaurent@google.com diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java index d331126e4194..50af60a0ad92 100644 --- a/media/java/android/media/tv/tuner/Tuner.java +++ b/media/java/android/media/tv/tuner/Tuner.java @@ -353,13 +353,16 @@ public class Tuner implements AutoCloseable { @Override public void close() { if (mFrontendHandle != null) { - nativeCloseFrontendByHandle(mFrontendHandle); + int res = nativeCloseFrontend(mFrontendHandle); + if (res != Tuner.RESULT_SUCCESS) { + TunerUtils.throwExceptionForResult(res, "failed to close frontend"); + } mTunerResourceManager.releaseFrontend(mFrontendHandle, mClientId); mFrontendHandle = null; mFrontend = null; } if (mLnb != null) { - releaseLnb(); + mLnb.close(); } if (!mDescramblers.isEmpty()) { for (Map.Entry<Integer, Descrambler> d : mDescramblers.entrySet()) { @@ -374,6 +377,14 @@ public class Tuner implements AutoCloseable { } mFilters.clear(); } + if (mDemuxHandle != null) { + int res = nativeCloseDemux(mDemuxHandle); + if (res != Tuner.RESULT_SUCCESS) { + TunerUtils.throwExceptionForResult(res, "failed to close demux"); + } + mTunerResourceManager.releaseDemux(mDemuxHandle, mClientId); + mFrontendHandle = null; + } TunerUtils.throwExceptionForResult(nativeClose(), "failed to close tuner"); } @@ -425,6 +436,8 @@ public class Tuner implements AutoCloseable { private static native DemuxCapabilities nativeGetDemuxCapabilities(); + private native int nativeCloseDemux(int handle); + private native int nativeCloseFrontend(int handle); private native int nativeClose(); @@ -545,10 +558,11 @@ public class Tuner implements AutoCloseable { @Result public int tune(@NonNull FrontendSettings settings) { mFrontendType = settings.getType(); - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND); - - mFrontendInfo = null; - return nativeTune(settings.getType(), settings); + if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) { + mFrontendInfo = null; + return nativeTune(settings.getType(), settings); + } + return RESULT_UNAVAILABLE; } /** @@ -584,11 +598,13 @@ public class Tuner implements AutoCloseable { + "started."); } mFrontendType = settings.getType(); - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND); - mScanCallback = scanCallback; - mScanCallbackExecutor = executor; - mFrontendInfo = null; - return nativeScan(settings.getType(), settings, scanType); + if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) { + mScanCallback = scanCallback; + mScanCallbackExecutor = executor; + mFrontendInfo = null; + return nativeScan(settings.getType(), settings, scanType); + } + return RESULT_UNAVAILABLE; } /** @@ -671,7 +687,9 @@ public class Tuner implements AutoCloseable { * @return the id of hardware A/V sync. */ public int getAvSyncHwId(@NonNull Filter filter) { - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX); + if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) { + return INVALID_AV_SYNC_ID; + } Integer id = nativeGetAvSyncHwId(filter); return id == null ? INVALID_AV_SYNC_ID : id; } @@ -686,7 +704,9 @@ public class Tuner implements AutoCloseable { * @return the current timestamp of hardware A/V sync. */ public long getAvSyncTime(int avSyncHwId) { - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX); + if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) { + return INVALID_TIMESTAMP; + } Long time = nativeGetAvSyncTime(avSyncHwId); return time == null ? INVALID_TIMESTAMP : time; } @@ -702,8 +722,10 @@ public class Tuner implements AutoCloseable { */ @Result public int connectCiCam(int ciCamId) { - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX); - return nativeConnectCiCam(ciCamId); + if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) { + return nativeConnectCiCam(ciCamId); + } + return RESULT_UNAVAILABLE; } /** @@ -715,8 +737,10 @@ public class Tuner implements AutoCloseable { */ @Result public int disconnectCiCam() { - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX); - return nativeDisconnectCiCam(); + if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) { + return nativeDisconnectCiCam(); + } + return RESULT_UNAVAILABLE; } /** @@ -726,7 +750,9 @@ public class Tuner implements AutoCloseable { */ @Nullable public FrontendInfo getFrontendInfo() { - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND); + if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) { + return null; + } if (mFrontend == null) { throw new IllegalStateException("frontend is not initialized"); } @@ -861,7 +887,9 @@ public class Tuner implements AutoCloseable { public Filter openFilter(@Type int mainType, @Subtype int subType, @BytesLong long bufferSize, @CallbackExecutor @Nullable Executor executor, @Nullable FilterCallback cb) { - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX); + if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) { + return null; + } Filter filter = nativeOpenFilter( mainType, TunerUtils.getFilterSubtype(mainType, subType), bufferSize); if (filter != null) { @@ -891,12 +919,15 @@ public class Tuner implements AutoCloseable { Objects.requireNonNull(executor, "executor must not be null"); Objects.requireNonNull(cb, "LnbCallback must not be null"); if (mLnb != null) { + mLnb.setCallback(executor, cb, this); return mLnb; } if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB) && mLnb != null) { mLnb.setCallback(executor, cb, this); + setLnb(mLnb); + return mLnb; } - return mLnb; + return null; } /** @@ -922,6 +953,7 @@ public class Tuner implements AutoCloseable { } mLnb = newLnb; mLnb.setCallback(executor, cb, this); + setLnb(mLnb); } return mLnb; } @@ -944,7 +976,9 @@ public class Tuner implements AutoCloseable { */ @Nullable public TimeFilter openTimeFilter() { - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX); + if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) { + return null; + } return nativeOpenTimeFilter(); } @@ -956,6 +990,9 @@ public class Tuner implements AutoCloseable { @RequiresPermission(android.Manifest.permission.ACCESS_TV_DESCRAMBLER) @Nullable public Descrambler openDescrambler() { + if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) { + return null; + } return requestDescrambler(); } @@ -976,7 +1013,9 @@ public class Tuner implements AutoCloseable { @NonNull OnRecordStatusChangedListener l) { Objects.requireNonNull(executor, "executor must not be null"); Objects.requireNonNull(l, "OnRecordStatusChangedListener must not be null"); - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX); + if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) { + return null; + } DvrRecorder dvr = nativeOpenDvrRecorder(bufferSize); dvr.setListener(executor, l); return dvr; @@ -999,7 +1038,9 @@ public class Tuner implements AutoCloseable { @NonNull OnPlaybackStatusChangedListener l) { Objects.requireNonNull(executor, "executor must not be null"); Objects.requireNonNull(l, "OnPlaybackStatusChangedListener must not be null"); - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX); + if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) { + return null; + } DvrPlayback dvr = nativeOpenDvrPlayback(bufferSize); dvr.setListener(executor, l); return dvr; diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java index e6962a14a2d0..aba74e518a22 100755 --- a/media/java/android/mtp/MtpDatabase.java +++ b/media/java/android/mtp/MtpDatabase.java @@ -46,6 +46,7 @@ import android.view.Display; import android.view.WindowManager; import com.android.internal.annotations.VisibleForNative; +import com.android.internal.annotations.VisibleForTesting; import dalvik.system.CloseGuard; @@ -408,7 +409,8 @@ public class MtpDatabase implements AutoCloseable { } @VisibleForNative - private int beginSendObject(String path, int format, int parent, int storageId) { + @VisibleForTesting + public int beginSendObject(String path, int format, int parent, int storageId) { MtpStorageManager.MtpObject parentObj = parent == 0 ? mManager.getStorageRoot(storageId) : mManager.getObject(parent); if (parentObj == null) { @@ -452,7 +454,8 @@ public class MtpDatabase implements AutoCloseable { } @VisibleForNative - private int getNumObjects(int storageID, int format, int parent) { + @VisibleForTesting + public int getNumObjects(int storageID, int format, int parent) { List<MtpStorageManager.MtpObject> objs = mManager.getObjects(parent, format, storageID); if (objs == null) { @@ -830,7 +833,8 @@ public class MtpDatabase implements AutoCloseable { } @VisibleForNative - private boolean getThumbnailInfo(int handle, long[] outLongs) { + @VisibleForTesting + public boolean getThumbnailInfo(int handle, long[] outLongs) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) { return false; @@ -866,7 +870,8 @@ public class MtpDatabase implements AutoCloseable { } @VisibleForNative - private byte[] getThumbnailData(int handle) { + @VisibleForTesting + public byte[] getThumbnailData(int handle) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) { return null; diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java index ba752633718c..88c32a3ea72b 100644 --- a/media/java/android/mtp/MtpStorage.java +++ b/media/java/android/mtp/MtpStorage.java @@ -36,7 +36,7 @@ public class MtpStorage { public MtpStorage(StorageVolume volume, int storageId) { mStorageId = storageId; - mPath = volume.getInternalPath(); + mPath = volume.getPath(); mDescription = volume.getDescription(null); mRemovable = volume.isRemovable(); mMaxFileSize = volume.getMaxFileSize(); diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 614fe73a76de..ab311c0e245a 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -1130,7 +1130,7 @@ jintArray JTuner::getLnbIds() { lnbIds = ids; res = r; }); - if (res != Result::SUCCESS || mLnbIds.size() == 0) { + if (res != Result::SUCCESS || lnbIds.size() == 0) { ALOGW("Lnb isn't available"); return NULL; } @@ -1797,6 +1797,22 @@ jobject JTuner::getFrontendStatus(jintArray types) { return statusObj; } +jint JTuner::closeFrontend() { + Result r = Result::SUCCESS; + if (mFe != NULL) { + r = mFe->close(); + } + return (jint) r; +} + +jint JTuner::closeDemux() { + Result r = Result::SUCCESS; + if (mDemux != NULL) { + r = mDemux->close(); + } + return (jint) r; +} + } // namespace android //////////////////////////////////////////////////////////////////////////////// @@ -3199,6 +3215,16 @@ static jint android_media_tv_Tuner_close_tuner(JNIEnv* env, jobject thiz) { return (jint) tuner->close(); } +static jint android_media_tv_Tuner_close_demux(JNIEnv* env, jobject thiz, jint /* handle */) { + sp<JTuner> tuner = getTuner(env, thiz); + return tuner->closeDemux(); +} + +static jint android_media_tv_Tuner_close_frontend(JNIEnv* env, jobject thiz, jint /* handle */) { + sp<JTuner> tuner = getTuner(env, thiz); + return tuner->closeFrontend(); +} + static jint android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobject filter) { sp<Dvr> dvrSp = getDvr(env, dvr); if (dvrSp == NULL) { @@ -3526,7 +3552,9 @@ static const JNINativeMethod gTunerMethods[] = { { "nativeGetDemuxCapabilities", "()Landroid/media/tv/tuner/DemuxCapabilities;", (void *)android_media_tv_Tuner_get_demux_caps }, { "nativeOpenDemuxByhandle", "(I)I", (void *)android_media_tv_Tuner_open_demux }, - {"nativeClose", "()I", (void *)android_media_tv_Tuner_close_tuner }, + { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_tuner }, + { "nativeCloseFrontend", "(I)I", (void *)android_media_tv_Tuner_close_frontend }, + { "nativeCloseDemux", "(I)I", (void *)android_media_tv_Tuner_close_demux }, }; static const JNINativeMethod gFilterMethods[] = { diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h index 750b146dbd59..3da78acb2f90 100644 --- a/media/jni/android_media_tv_Tuner.h +++ b/media/jni/android_media_tv_Tuner.h @@ -191,6 +191,8 @@ struct JTuner : public RefBase { jobject getFrontendStatus(jintArray types); Result openDemux(); jint close(); + jint closeFrontend(); + jint closeDemux(); protected: virtual ~JTuner(); diff --git a/media/tests/MtpTests/res/raw/test_bad_thumb.jpg b/media/tests/MtpTests/res/raw/test_bad_thumb.jpg new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/media/tests/MtpTests/res/raw/test_bad_thumb.jpg diff --git a/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java b/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java new file mode 100644 index 000000000000..e2e8ff4946e0 --- /dev/null +++ b/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.mtp; + +import android.annotation.NonNull; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Build; +import android.os.FileUtils; +import android.os.UserHandle; +import android.os.storage.StorageManager; +import android.os.storage.StorageVolume; +import android.util.Log; + +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.internal.util.Preconditions; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Tests for MtpDatabase functionality. + */ +@RunWith(AndroidJUnit4.class) +public class MtpDatabaseTest { + private static final String TAG = MtpDatabaseTest.class.getSimpleName(); + + private final Context mContext = InstrumentationRegistry.getContext(); + + private static final File mBaseDir = InstrumentationRegistry.getContext().getExternalCacheDir(); + private static final String MAIN_STORAGE_DIR = mBaseDir.getPath() + "/" + TAG + "/"; + private static final String TEST_DIRNAME = "/TestIs"; + + private static final int MAIN_STORAGE_ID = 0x10001; + private static final int SCND_STORAGE_ID = 0x20001; + private static final String MAIN_STORAGE_ID_STR = Integer.toHexString(MAIN_STORAGE_ID); + private static final String SCND_STORAGE_ID_STR = Integer.toHexString(SCND_STORAGE_ID); + + private static final File mMainStorageDir = new File(MAIN_STORAGE_DIR); + + private static ServerHolder mServerHolder; + private MtpDatabase mMtpDatabase; + + private static void logMethodName() { + Log.d(TAG, Thread.currentThread().getStackTrace()[3].getMethodName()); + } + + private static File createNewDir(File parent, String name) { + File ret = new File(parent, name); + if (!ret.mkdir()) + throw new AssertionError( + "Failed to create file: name=" + name + ", " + parent.getPath()); + return ret; + } + + private static void writeNewFile(File newFile) { + try { + new FileOutputStream(newFile).write(new byte[] {0, 0, 0}); + } catch (IOException e) { + Assert.fail(); + } + } + + private static void writeNewFileFromByte(File newFile, byte[] byteData) { + try { + new FileOutputStream(newFile).write(byteData); + } catch (IOException e) { + Assert.fail(); + } + } + + private static class ServerHolder { + @NonNull final MtpServer server; + @NonNull final MtpDatabase database; + + ServerHolder(@NonNull MtpServer server, @NonNull MtpDatabase database) { + Preconditions.checkNotNull(server); + Preconditions.checkNotNull(database); + this.server = server; + this.database = database; + } + + void close() { + this.database.setServer(null); + } + } + + private class OnServerTerminated implements Runnable { + @Override + public void run() { + if (mServerHolder == null) { + Log.e(TAG, "mServerHolder is unexpectedly null."); + return; + } + mServerHolder.close(); + mServerHolder = null; + } + } + + @Before + public void setUp() { + FileUtils.deleteContentsAndDir(mMainStorageDir); + Assert.assertTrue(mMainStorageDir.mkdir()); + + StorageVolume mainStorage = new StorageVolume(MAIN_STORAGE_ID_STR, + mMainStorageDir, mMainStorageDir, "Primary Storage", + true, false, true, false, -1, UserHandle.CURRENT, "", ""); + + final StorageVolume primary = mainStorage; + + mMtpDatabase = new MtpDatabase(mContext, null); + + final MtpServer server = + new MtpServer(mMtpDatabase, null, false, + new OnServerTerminated(), Build.MANUFACTURER, + Build.MODEL, "1.0"); + mMtpDatabase.setServer(server); + mServerHolder = new ServerHolder(server, mMtpDatabase); + + mMtpDatabase.addStorage(mainStorage); + } + + @After + public void tearDown() { + FileUtils.deleteContentsAndDir(mMainStorageDir); + } + + private File stageFile(int resId, File file) throws IOException { + try (InputStream source = mContext.getResources().openRawResource(resId); + OutputStream target = new FileOutputStream(file)) { + android.os.FileUtils.copy(source, target); + } + return file; + } + + /** + * Refer to BitmapUtilTests, but keep here, + * so as to be aware of the behavior or interface change there + */ + private void assertBitmapSize(int expectedWidth, int expectedHeight, Bitmap bitmap) { + Assert.assertTrue( + "Abnormal bitmap.width: " + bitmap.getWidth(), bitmap.getWidth() >= expectedWidth); + Assert.assertTrue( + "Abnormal bitmap.height: " + bitmap.getHeight(), + bitmap.getHeight() >= expectedHeight); + } + + private byte[] createJpegRawData(int sourceWidth, int sourceHeight) throws IOException { + return createRawData(Bitmap.CompressFormat.JPEG, sourceWidth, sourceHeight); + } + + private byte[] createPngRawData(int sourceWidth, int sourceHeight) throws IOException { + return createRawData(Bitmap.CompressFormat.PNG, sourceWidth, sourceHeight); + } + + private byte[] createRawData(Bitmap.CompressFormat format, int sourceWidth, int sourceHeight) + throws IOException { + // Create a temp bitmap as our source + Bitmap b = Bitmap.createBitmap(sourceWidth, sourceHeight, Bitmap.Config.ARGB_8888); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + b.compress(format, 50, outputStream); + final byte[] data = outputStream.toByteArray(); + outputStream.close(); + return data; + } + + /** + * Decodes the bitmap with the given sample size + */ + public static Bitmap decodeBitmapFromBytes(byte[] bytes, int sampleSize) { + final BitmapFactory.Options options; + if (sampleSize <= 1) { + options = null; + } else { + options = new BitmapFactory.Options(); + options.inSampleSize = sampleSize; + } + return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options); + } + + private void testThumbnail(int fileHandle, File imgFile, boolean isGoodThumb) + throws IOException { + boolean isValidThumb; + byte[] byteArray; + long[] outLongs = new long[3]; + + isValidThumb = mMtpDatabase.getThumbnailInfo(fileHandle, outLongs); + Assert.assertTrue(isValidThumb); + + byteArray = mMtpDatabase.getThumbnailData(fileHandle); + + if (isGoodThumb) { + Assert.assertNotNull("Fail to generate thumbnail:" + imgFile.getPath(), byteArray); + + Bitmap testBitmap = decodeBitmapFromBytes(byteArray, 4); + assertBitmapSize(32, 16, testBitmap); + } else Assert.assertNull("Bad image should return null:" + imgFile.getPath(), byteArray); + } + + @Test + @SmallTest + public void testMtpDatabaseThumbnail() throws IOException { + int baseHandle; + int handleJpgBadThumb, handleJpgNoThumb, handleJpgBad; + int handlePng1, handlePngBad; + final String baseTestDirStr = mMainStorageDir.getPath() + TEST_DIRNAME; + + logMethodName(); + + Log.d(TAG, "testMtpDatabaseThumbnail: Generate and insert tested files."); + + baseHandle = mMtpDatabase.beginSendObject(baseTestDirStr, + MtpConstants.FORMAT_ASSOCIATION, 0, MAIN_STORAGE_ID); + + File baseDir = new File(baseTestDirStr); + baseDir.mkdirs(); + + final File jpgfileBadThumb = new File(baseDir, "jpgfileBadThumb.jpg"); + final File jpgFileNoThumb = new File(baseDir, "jpgFileNoThumb.jpg"); + final File jpgfileBad = new File(baseDir, "jpgfileBad.jpg"); + final File pngFile1 = new File(baseDir, "pngFile1.png"); + final File pngFileBad = new File(baseDir, "pngFileBad.png"); + + handleJpgBadThumb = mMtpDatabase.beginSendObject(jpgfileBadThumb.getPath(), + MtpConstants.FORMAT_EXIF_JPEG, baseHandle, MAIN_STORAGE_ID); + stageFile(R.raw.test_bad_thumb, jpgfileBadThumb); + + handleJpgNoThumb = mMtpDatabase.beginSendObject(jpgFileNoThumb.getPath(), + MtpConstants.FORMAT_EXIF_JPEG, baseHandle, MAIN_STORAGE_ID); + writeNewFileFromByte(jpgFileNoThumb, createJpegRawData(128, 64)); + + handleJpgBad = mMtpDatabase.beginSendObject(jpgfileBad.getPath(), + MtpConstants.FORMAT_EXIF_JPEG, baseHandle, MAIN_STORAGE_ID); + writeNewFile(jpgfileBad); + + handlePng1 = mMtpDatabase.beginSendObject(pngFile1.getPath(), + MtpConstants.FORMAT_PNG, baseHandle, MAIN_STORAGE_ID); + writeNewFileFromByte(pngFile1, createPngRawData(128, 64)); + + handlePngBad = mMtpDatabase.beginSendObject(pngFileBad.getPath(), + MtpConstants.FORMAT_PNG, baseHandle, MAIN_STORAGE_ID); + writeNewFile(pngFileBad); + + Log.d(TAG, "testMtpDatabaseThumbnail: Test bad JPG"); + + testThumbnail(handleJpgBadThumb, jpgfileBadThumb, false); + + testThumbnail(handleJpgNoThumb, jpgFileNoThumb, false); + + testThumbnail(handleJpgBad, jpgfileBad, false); + + Log.d(TAG, "testMtpDatabaseThumbnail: Test PNG"); + + testThumbnail(handlePng1, pngFile1, true); + + Log.d(TAG, "testMtpDatabaseThumbnail: Test bad PNG"); + + testThumbnail(handlePngBad, pngFileBad, false); + } + + @Test + @SmallTest + public void testMtpDatabaseExtStorage() throws IOException { + int numObj; + StorageVolume[] mVolumes; + + logMethodName(); + + mVolumes = StorageManager.getVolumeList(UserHandle.myUserId(), 0); + // Currently it may need manual setup for 2nd storage on virtual device testing. + // Thus only run test when 2nd storage exists. + Assume.assumeTrue( + "Skip when 2nd storage not available, volume numbers = " + mVolumes.length, + mVolumes.length >= 2); + + for (int ii = 0; ii < mVolumes.length; ii++) { + StorageVolume volume = mVolumes[ii]; + // Skip Actual Main storage (Internal Storage), + // since we use manipulated path as testing Main storage + if (ii > 0) + mMtpDatabase.addStorage(volume); + } + + numObj = mMtpDatabase.getNumObjects(SCND_STORAGE_ID, 0, 0xFFFFFFFF); + Assert.assertTrue( + "Fail to get objects in 2nd storage, object numbers = " + numObj, numObj >= 0); + } +} diff --git a/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml index 71e74cff6ccb..d0916b518c92 100644 --- a/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml +++ b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml @@ -17,7 +17,7 @@ */ --> -<com.android.systemui.navigationbar.car.CarNavigationBarView +<com.android.systemui.car.navigationbar.CarNavigationBarView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:layout_height="match_parent" @@ -36,7 +36,7 @@ android:background="@drawable/system_bar_background" android:animateLayoutChanges="true"> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/home" android:layout_height="wrap_content" android:layout_width="match_parent" @@ -47,7 +47,7 @@ android:paddingBottom="30dp" /> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/grid" android:layout_height="wrap_content" android:layout_width="match_parent" @@ -59,7 +59,7 @@ android:paddingBottom="30dp" /> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/hvac" android:layout_height="wrap_content" android:layout_width="match_parent" @@ -110,4 +110,4 @@ </LinearLayout> -</com.android.systemui.navigationbar.car.CarNavigationBarView> +</com.android.systemui.car.navigationbar.CarNavigationBarView> diff --git a/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml index f016dbfaa3b7..de5a15068a5c 100644 --- a/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml +++ b/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml @@ -17,7 +17,7 @@ */ --> -<com.android.systemui.navigationbar.car.CarNavigationBarView +<com.android.systemui.car.navigationbar.CarNavigationBarView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:layout_height="match_parent" @@ -36,7 +36,7 @@ android:background="@drawable/system_bar_background" android:animateLayoutChanges="true"> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/home" android:layout_height="wrap_content" android:layout_width="match_parent" @@ -47,7 +47,7 @@ android:paddingBottom="30dp" /> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/hvac" android:layout_height="wrap_content" android:layout_width="match_parent" @@ -59,4 +59,4 @@ android:paddingBottom="30dp" /> </LinearLayout> -</com.android.systemui.navigationbar.car.CarNavigationBarView> +</com.android.systemui.car.navigationbar.CarNavigationBarView> diff --git a/packages/CarSystemUI/res/layout/car_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_navigation_bar.xml index e2e9a336d614..1418bf8604bf 100644 --- a/packages/CarSystemUI/res/layout/car_navigation_bar.xml +++ b/packages/CarSystemUI/res/layout/car_navigation_bar.xml @@ -15,7 +15,7 @@ ~ limitations under the License --> -<com.android.systemui.navigationbar.car.CarNavigationBarView +<com.android.systemui.car.navigationbar.CarNavigationBarView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" @@ -33,7 +33,7 @@ android:paddingEnd="20dp" android:gravity="center"> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/home" style="@style/NavigationBarButton" systemui:componentNames="com.android.car.carlauncher/.CarLauncher" @@ -48,7 +48,7 @@ android:layout_height="match_parent" android:layout_weight="1"/> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/maps_nav" style="@style/NavigationBarButton" systemui:categories="android.intent.category.APP_MAPS" @@ -63,7 +63,7 @@ android:layout_height="match_parent" android:layout_weight="1"/> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/music_nav" style="@style/NavigationBarButton" systemui:categories="android.intent.category.APP_MUSIC" @@ -79,7 +79,7 @@ android:layout_height="match_parent" android:layout_weight="1"/> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/phone_nav" style="@style/NavigationBarButton" systemui:icon="@drawable/car_ic_phone" @@ -94,7 +94,7 @@ android:layout_height="match_parent" android:layout_weight="1"/> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/grid_nav" style="@style/NavigationBarButton" systemui:componentNames="com.android.car.carlauncher/.AppGridActivity" @@ -109,7 +109,7 @@ android:layout_height="match_parent" android:layout_weight="1"/> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/notifications" style="@style/NavigationBarButton" systemui:icon="@drawable/car_ic_notification" @@ -121,7 +121,7 @@ android:layout_height="match_parent" android:layout_weight="1"/> - <com.android.systemui.navigationbar.car.AssitantButton + <com.android.systemui.car.navigationbar.AssitantButton android:id="@+id/assist" style="@style/NavigationBarButton" systemui:icon="@drawable/ic_mic_white" @@ -140,4 +140,4 @@ android:visibility="gone" /> -</com.android.systemui.navigationbar.car.CarNavigationBarView>
\ No newline at end of file +</com.android.systemui.car.navigationbar.CarNavigationBarView>
\ No newline at end of file diff --git a/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml index 1c5d37ffd60f..a040e800cbfc 100644 --- a/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml +++ b/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml @@ -15,7 +15,7 @@ ~ limitations under the License --> -<com.android.systemui.navigationbar.car.CarNavigationBarView +<com.android.systemui.car.navigationbar.CarNavigationBarView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" @@ -31,7 +31,7 @@ android:paddingStart="@*android:dimen/car_padding_5" android:paddingEnd="@*android:dimen/car_padding_5"> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/home" android:layout_width="@*android:dimen/car_touch_target_size" android:layout_height="match_parent" @@ -42,5 +42,5 @@ systemui:highlightWhenSelected="true" /> </LinearLayout> -</com.android.systemui.navigationbar.car.CarNavigationBarView> +</com.android.systemui.car.navigationbar.CarNavigationBarView> diff --git a/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml index 327610a892ee..d386ce3300e6 100644 --- a/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml +++ b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml @@ -17,7 +17,7 @@ */ --> -<com.android.systemui.navigationbar.car.CarNavigationBarView +<com.android.systemui.car.navigationbar.CarNavigationBarView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:layout_height="match_parent" @@ -39,7 +39,7 @@ android:background="@drawable/system_bar_background" android:animateLayoutChanges="true"> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/home" android:layout_height="wrap_content" android:layout_width="match_parent" @@ -50,7 +50,7 @@ android:paddingBottom="30dp" /> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/grid" android:layout_height="wrap_content" android:layout_width="match_parent" @@ -62,7 +62,7 @@ android:paddingBottom="30dp" /> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/hvac" android:layout_height="wrap_content" android:layout_width="match_parent" @@ -113,4 +113,4 @@ </LinearLayout> -</com.android.systemui.navigationbar.car.CarNavigationBarView> +</com.android.systemui.car.navigationbar.CarNavigationBarView> diff --git a/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml index f016dbfaa3b7..de5a15068a5c 100644 --- a/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml +++ b/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml @@ -17,7 +17,7 @@ */ --> -<com.android.systemui.navigationbar.car.CarNavigationBarView +<com.android.systemui.car.navigationbar.CarNavigationBarView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:layout_height="match_parent" @@ -36,7 +36,7 @@ android:background="@drawable/system_bar_background" android:animateLayoutChanges="true"> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/home" android:layout_height="wrap_content" android:layout_width="match_parent" @@ -47,7 +47,7 @@ android:paddingBottom="30dp" /> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/hvac" android:layout_height="wrap_content" android:layout_width="match_parent" @@ -59,4 +59,4 @@ android:paddingBottom="30dp" /> </LinearLayout> -</com.android.systemui.navigationbar.car.CarNavigationBarView> +</com.android.systemui.car.navigationbar.CarNavigationBarView> diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml index ce0d31c6cc47..3389a7a8c6af 100644 --- a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml +++ b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml @@ -15,7 +15,7 @@ ~ limitations under the License --> -<com.android.systemui.navigationbar.car.CarNavigationBarView +<com.android.systemui.car.navigationbar.CarNavigationBarView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:id="@+id/car_top_bar" @@ -36,7 +36,7 @@ android:layout_alignParentStart="true" > - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/hvacleft" android:layout_width="match_parent" android:layout_height="match_parent" @@ -45,7 +45,7 @@ systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end" /> - <com.android.systemui.statusbar.hvac.AnimatedTemperatureView + <com.android.systemui.car.hvac.AnimatedTemperatureView android:id="@+id/lefttext" android:layout_width="wrap_content" android:layout_height="match_parent" @@ -71,7 +71,7 @@ android:layout_height="match_parent" android:layout_centerInParent="true" > - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/qs" android:layout_width="match_parent" android:layout_height="match_parent" @@ -118,7 +118,7 @@ android:layout_alignParentEnd="true" > - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/hvacright" android:layout_width="match_parent" android:layout_height="match_parent" @@ -127,7 +127,7 @@ systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end" /> - <com.android.systemui.statusbar.hvac.AnimatedTemperatureView + <com.android.systemui.car.hvac.AnimatedTemperatureView android:id="@+id/righttext" android:layout_width="wrap_content" android:layout_height="match_parent" @@ -148,4 +148,4 @@ </FrameLayout> </RelativeLayout> -</com.android.systemui.navigationbar.car.CarNavigationBarView> +</com.android.systemui.car.navigationbar.CarNavigationBarView> diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml index a71567c48eaf..9634950e4748 100644 --- a/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml +++ b/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml @@ -15,7 +15,7 @@ ~ limitations under the License --> -<com.android.systemui.navigationbar.car.CarNavigationBarView +<com.android.systemui.car.navigationbar.CarNavigationBarView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:id="@+id/car_top_bar" @@ -36,7 +36,7 @@ android:layout_alignParentStart="true" > - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/hvacleft" android:layout_width="match_parent" android:layout_height="match_parent" @@ -45,7 +45,7 @@ systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end" /> - <com.android.systemui.statusbar.hvac.AnimatedTemperatureView + <com.android.systemui.car.hvac.AnimatedTemperatureView android:id="@+id/lefttext" android:layout_width="wrap_content" android:layout_height="match_parent" @@ -70,7 +70,7 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_centerInParent="true"> - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/qs" android:layout_width="match_parent" android:layout_height="match_parent" @@ -114,7 +114,7 @@ android:layout_alignParentEnd="true" > - <com.android.systemui.navigationbar.car.CarNavigationButton + <com.android.systemui.car.navigationbar.CarNavigationButton android:id="@+id/hvacright" android:layout_width="match_parent" android:layout_height="match_parent" @@ -123,7 +123,7 @@ systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end" /> - <com.android.systemui.statusbar.hvac.AnimatedTemperatureView + <com.android.systemui.car.hvac.AnimatedTemperatureView android:id="@+id/righttext" android:layout_width="wrap_content" android:layout_height="match_parent" @@ -144,4 +144,4 @@ </FrameLayout> </RelativeLayout> -</com.android.systemui.navigationbar.car.CarNavigationBarView> +</com.android.systemui.car.navigationbar.CarNavigationBarView> diff --git a/packages/CarSystemUI/res/values-af/strings.xml b/packages/CarSystemUI/res/values-af/strings.xml index 8eba6dc8fccf..8a54c3bf4460 100644 --- a/packages/CarSystemUI/res/values-af/strings.xml +++ b/packages/CarSystemUI/res/values-af/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Stemherkenning nou deur gekoppelde Bluetooth-toestel hanteer"</string> + <string name="car_guest" msgid="318393171202663722">"Gas"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gas"</string> + <string name="car_add_user" msgid="4067337059622483269">"Voeg gebruiker by"</string> + <string name="car_new_user" msgid="6637442369728092473">"Nuwe gebruiker"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Wanneer jy \'n nuwe gebruiker byvoeg, moet daardie persoon hul spasie opstel."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Enige gebruiker kan programme vir al die ander gebruikers opdateer."</string> </resources> diff --git a/packages/CarSystemUI/res/values-am/strings.xml b/packages/CarSystemUI/res/values-am/strings.xml index 1e971b43f143..733349ce79cf 100644 --- a/packages/CarSystemUI/res/values-am/strings.xml +++ b/packages/CarSystemUI/res/values-am/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"ዝቅተኛ"</string> <string name="hvac_max_text" msgid="3669693372074755551">"ከፍተኛ"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"የድምፅ ለይቶ ማወቅ አሁን በተገናኘ የብሉቱዝ መሣሪያ ይስተናገዳል"</string> + <string name="car_guest" msgid="318393171202663722">"እንግዳ"</string> + <string name="start_guest_session" msgid="497784785761754874">"እንግዳ"</string> + <string name="car_add_user" msgid="4067337059622483269">"ተጠቃሚ አክል"</string> + <string name="car_new_user" msgid="6637442369728092473">"አዲስ ተጠቃሚ"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"አዲስ ተጠቃሚ ሲያክሉ ያ ሰው የራሳቸውን ቦታ ማቀናበር አለባቸው።"</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"ማንኛውም ተጠቃሚ መተግበሪያዎችን ለሌሎች ተጠቃሚዎች ሁሉ ማዘመን ይችላል።"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ar/strings.xml b/packages/CarSystemUI/res/values-ar/strings.xml new file mode 100644 index 000000000000..320df5870fe3 --- /dev/null +++ b/packages/CarSystemUI/res/values-ar/strings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="hvac_min_text" msgid="8167124789068494624">"حد أدنى"</string> + <string name="hvac_max_text" msgid="3669693372074755551">"حد أقصى"</string> + <string name="voice_recognition_toast" msgid="1149934534584052842">"تتم معالجة التعرّف على الصوت الآن من خلال جهاز بلوتوث متصل."</string> + <string name="car_guest" msgid="318393171202663722">"ضيف"</string> + <string name="start_guest_session" msgid="497784785761754874">"ضيف"</string> + <string name="car_add_user" msgid="4067337059622483269">"إضافة مستخدم"</string> + <string name="car_new_user" msgid="6637442369728092473">"مستخدم جديد"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"عند إضافة مستخدم جديد، على هذا المستخدم إعداد مساحته."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"يمكن لأي مستخدم تحديث التطبيقات لجميع المستخدمين الآخرين."</string> +</resources> diff --git a/packages/CarSystemUI/res/values-az/strings.xml b/packages/CarSystemUI/res/values-az/strings.xml index 1caf65a75950..98dd49b4f9ff 100644 --- a/packages/CarSystemUI/res/values-az/strings.xml +++ b/packages/CarSystemUI/res/values-az/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Səs tanınması qoşulmuş Bluetooth cihazı ilə icra edilir"</string> + <string name="car_guest" msgid="318393171202663722">"Qonaq"</string> + <string name="start_guest_session" msgid="497784785761754874">"Qonaq"</string> + <string name="car_add_user" msgid="4067337059622483269">"İstifadəçi əlavə edin"</string> + <string name="car_new_user" msgid="6637442369728092473">"Yeni İstifadəçi"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Yeni istifadəçi əlavə etdiyinizdə həmin şəxs öz yerini təyin etməlidir."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"İstənilən istifadəçi digər bütün istifadəçilər üçün tətbiqləri güncəlləyə bilər."</string> </resources> diff --git a/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml b/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml index e0a34fd6bc82..3f01a3ac4845 100644 --- a/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Prepoznavanjem glasa sada upravlja povezani Bluetooth uređaj"</string> + <string name="car_guest" msgid="318393171202663722">"Gost"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gost"</string> + <string name="car_add_user" msgid="4067337059622483269">"Dodaj korisnika"</string> + <string name="car_new_user" msgid="6637442369728092473">"Novi korisnik"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kada dodate novog korisnika, ta osoba treba da podesi svoj prostor."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Svaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string> </resources> diff --git a/packages/CarSystemUI/res/values-be/strings.xml b/packages/CarSystemUI/res/values-be/strings.xml index 8c58c54cddd0..1b26c370f958 100644 --- a/packages/CarSystemUI/res/values-be/strings.xml +++ b/packages/CarSystemUI/res/values-be/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Мін"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Макс"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Распазнаванне голасу выконвае падключаная прылада Bluetooth"</string> + <string name="car_guest" msgid="318393171202663722">"Госць"</string> + <string name="start_guest_session" msgid="497784785761754874">"Госць"</string> + <string name="car_add_user" msgid="4067337059622483269">"Дадаць карыстальніка"</string> + <string name="car_new_user" msgid="6637442369728092473">"Новы карыстальнік"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Калі вы дадаяце новага карыстальніка, яму трэба наладзіць свой профіль."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Кожны карыстальнік прылады можа абнаўляць праграмы для ўсіх іншых карыстальнікаў."</string> </resources> diff --git a/packages/CarSystemUI/res/values-bg/strings.xml b/packages/CarSystemUI/res/values-bg/strings.xml index c63830407ea7..dda69ecd7f86 100644 --- a/packages/CarSystemUI/res/values-bg/strings.xml +++ b/packages/CarSystemUI/res/values-bg/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Гл. разпознаване се обработва от свързаното у-во с Bluetooth"</string> + <string name="car_guest" msgid="318393171202663722">"Гост"</string> + <string name="start_guest_session" msgid="497784785761754874">"Гост"</string> + <string name="car_add_user" msgid="4067337059622483269">"Добавяне на потребител"</string> + <string name="car_new_user" msgid="6637442369728092473">"Нов потребител"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Когато добавите нов потребител, той трябва да настрои работната си област."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Всеки потребител може да актуализира приложенията за всички останали потребители."</string> </resources> diff --git a/packages/CarSystemUI/res/values-bn/strings.xml b/packages/CarSystemUI/res/values-bn/strings.xml index db072dfd2868..1c56256a59a5 100644 --- a/packages/CarSystemUI/res/values-bn/strings.xml +++ b/packages/CarSystemUI/res/values-bn/strings.xml @@ -20,4 +20,16 @@ <string name="hvac_min_text" msgid="8167124789068494624">"সর্বনিম্ন"</string> <string name="hvac_max_text" msgid="3669693372074755551">"সর্বাধিক"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"কানেক্ট করা ব্লুটুথ ডিভাইস এখন ভয়েস শনাক্তকরণ ম্যানেজ করছে"</string> + <!-- no translation found for car_guest (318393171202663722) --> + <skip /> + <!-- no translation found for start_guest_session (497784785761754874) --> + <skip /> + <!-- no translation found for car_add_user (4067337059622483269) --> + <skip /> + <!-- no translation found for car_new_user (6637442369728092473) --> + <skip /> + <!-- no translation found for user_add_user_message_setup (1035578846007352323) --> + <skip /> + <!-- no translation found for user_add_user_message_update (7061671307004867811) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-bs/strings.xml b/packages/CarSystemUI/res/values-bs/strings.xml index e0a34fd6bc82..4b096d6d754c 100644 --- a/packages/CarSystemUI/res/values-bs/strings.xml +++ b/packages/CarSystemUI/res/values-bs/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Prepoznavanjem glasa sada upravlja povezani Bluetooth uređaj"</string> + <string name="car_guest" msgid="318393171202663722">"Gost"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gost"</string> + <string name="car_add_user" msgid="4067337059622483269">"Dodaj korisnika"</string> + <string name="car_new_user" msgid="6637442369728092473">"Novi korisnik"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kada dodate novog korisnika, ta osoba treba postaviti svoj prostor."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Bilo koji korisnik može ažurirati aplikacije za sve druge korisnike."</string> </resources> diff --git a/packages/CarSystemUI/res/values-ca/strings.xml b/packages/CarSystemUI/res/values-ca/strings.xml index 1d743f91e70d..a78bff192757 100644 --- a/packages/CarSystemUI/res/values-ca/strings.xml +++ b/packages/CarSystemUI/res/values-ca/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Mín."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Màx."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Reconeixement de veu gestionat per disp. Bluetooth connectat"</string> + <string name="car_guest" msgid="318393171202663722">"Convidat"</string> + <string name="start_guest_session" msgid="497784785761754874">"Convidat"</string> + <string name="car_add_user" msgid="4067337059622483269">"Afegeix un usuari"</string> + <string name="car_new_user" msgid="6637442369728092473">"Usuari nou"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar el seu espai."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string> </resources> diff --git a/packages/CarSystemUI/res/values-cs/strings.xml b/packages/CarSystemUI/res/values-cs/strings.xml index 5548252ccd4d..d2fdf36d0dc6 100644 --- a/packages/CarSystemUI/res/values-cs/strings.xml +++ b/packages/CarSystemUI/res/values-cs/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Rozpoznávání hlasu teď provádí připojené zařízení Bluetooth"</string> + <string name="car_guest" msgid="318393171202663722">"Host"</string> + <string name="start_guest_session" msgid="497784785761754874">"Host"</string> + <string name="car_add_user" msgid="4067337059622483269">"Přidat uživatele"</string> + <string name="car_new_user" msgid="6637442369728092473">"Nový uživatel"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Každý nově přidaný uživatel si musí nastavit vlastní prostor."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Každý uživatel může aktualizovat aplikace všech ostatních uživatelů."</string> </resources> diff --git a/packages/CarSystemUI/res/values-da/strings.xml b/packages/CarSystemUI/res/values-da/strings.xml index 141a795e2bdf..90bd0ac9cb8a 100644 --- a/packages/CarSystemUI/res/values-da/strings.xml +++ b/packages/CarSystemUI/res/values-da/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Talegenkendelse sker nu med den forbundne Blutetooth-enhed"</string> + <string name="car_guest" msgid="318393171202663722">"Gæst"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gæst"</string> + <string name="car_add_user" msgid="4067337059622483269">"Tilføj bruger"</string> + <string name="car_new_user" msgid="6637442369728092473">"Ny bruger"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Når du tilføjer en ny bruger, skal vedkommende konfigurere sit område."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Alle brugere kan opdatere apps for alle andre brugere."</string> </resources> diff --git a/packages/CarSystemUI/res/values-de/strings.xml b/packages/CarSystemUI/res/values-de/strings.xml index bfb27c23c8e4..e5695f7661c1 100644 --- a/packages/CarSystemUI/res/values-de/strings.xml +++ b/packages/CarSystemUI/res/values-de/strings.xml @@ -20,4 +20,16 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Spracherkennung jetzt über das verbundene Bluetooth-Gerät"</string> + <!-- no translation found for car_guest (318393171202663722) --> + <skip /> + <!-- no translation found for start_guest_session (497784785761754874) --> + <skip /> + <!-- no translation found for car_add_user (4067337059622483269) --> + <skip /> + <!-- no translation found for car_new_user (6637442369728092473) --> + <skip /> + <!-- no translation found for user_add_user_message_setup (1035578846007352323) --> + <skip /> + <!-- no translation found for user_add_user_message_update (7061671307004867811) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-el/strings.xml b/packages/CarSystemUI/res/values-el/strings.xml index d851133131f6..fcbb0fd4d575 100644 --- a/packages/CarSystemUI/res/values-el/strings.xml +++ b/packages/CarSystemUI/res/values-el/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Ελάχ."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Μεγ."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Φωνητική αναγνωση από συνδεδεμένη συσκευή Bluetooth"</string> + <string name="car_guest" msgid="318393171202663722">"Επισκέπτης"</string> + <string name="start_guest_session" msgid="497784785761754874">"Επισκέπτης"</string> + <string name="car_add_user" msgid="4067337059622483269">"Προσθήκη χρήστη"</string> + <string name="car_new_user" msgid="6637442369728092473">"Νέος χρήστης"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει τον χώρο του."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Οποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rAU/strings.xml b/packages/CarSystemUI/res/values-en-rAU/strings.xml index 617710a094d4..a87eb877e7c4 100644 --- a/packages/CarSystemUI/res/values-en-rAU/strings.xml +++ b/packages/CarSystemUI/res/values-en-rAU/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Voice recognition now handled by connected Bluetooth device"</string> + <string name="car_guest" msgid="318393171202663722">"Guest"</string> + <string name="start_guest_session" msgid="497784785761754874">"Guest"</string> + <string name="car_add_user" msgid="4067337059622483269">"Add user"</string> + <string name="car_new_user" msgid="6637442369728092473">"New user"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rCA/strings.xml b/packages/CarSystemUI/res/values-en-rCA/strings.xml index 617710a094d4..a87eb877e7c4 100644 --- a/packages/CarSystemUI/res/values-en-rCA/strings.xml +++ b/packages/CarSystemUI/res/values-en-rCA/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Voice recognition now handled by connected Bluetooth device"</string> + <string name="car_guest" msgid="318393171202663722">"Guest"</string> + <string name="start_guest_session" msgid="497784785761754874">"Guest"</string> + <string name="car_add_user" msgid="4067337059622483269">"Add user"</string> + <string name="car_new_user" msgid="6637442369728092473">"New user"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rGB/strings.xml b/packages/CarSystemUI/res/values-en-rGB/strings.xml index 617710a094d4..a87eb877e7c4 100644 --- a/packages/CarSystemUI/res/values-en-rGB/strings.xml +++ b/packages/CarSystemUI/res/values-en-rGB/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Voice recognition now handled by connected Bluetooth device"</string> + <string name="car_guest" msgid="318393171202663722">"Guest"</string> + <string name="start_guest_session" msgid="497784785761754874">"Guest"</string> + <string name="car_add_user" msgid="4067337059622483269">"Add user"</string> + <string name="car_new_user" msgid="6637442369728092473">"New user"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rIN/strings.xml b/packages/CarSystemUI/res/values-en-rIN/strings.xml index 617710a094d4..a87eb877e7c4 100644 --- a/packages/CarSystemUI/res/values-en-rIN/strings.xml +++ b/packages/CarSystemUI/res/values-en-rIN/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Voice recognition now handled by connected Bluetooth device"</string> + <string name="car_guest" msgid="318393171202663722">"Guest"</string> + <string name="start_guest_session" msgid="497784785761754874">"Guest"</string> + <string name="car_add_user" msgid="4067337059622483269">"Add user"</string> + <string name="car_new_user" msgid="6637442369728092473">"New user"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rXC/strings.xml b/packages/CarSystemUI/res/values-en-rXC/strings.xml index fec49f2c54d2..6821c3ec0913 100644 --- a/packages/CarSystemUI/res/values-en-rXC/strings.xml +++ b/packages/CarSystemUI/res/values-en-rXC/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Voice recognition now handled by connected Bluetooth device"</string> + <string name="car_guest" msgid="318393171202663722">"Guest"</string> + <string name="start_guest_session" msgid="497784785761754874">"Guest"</string> + <string name="car_add_user" msgid="4067337059622483269">"Add User"</string> + <string name="car_new_user" msgid="6637442369728092473">"New User"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> </resources> diff --git a/packages/CarSystemUI/res/values-es-rUS/strings.xml b/packages/CarSystemUI/res/values-es-rUS/strings.xml index e66891ff7c4a..060c81272a81 100644 --- a/packages/CarSystemUI/res/values-es-rUS/strings.xml +++ b/packages/CarSystemUI/res/values-es-rUS/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Mín."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Máx."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"El dispositivo Bluetooth administra el reconocimiento de voz"</string> + <string name="car_guest" msgid="318393171202663722">"Invitado"</string> + <string name="start_guest_session" msgid="497784785761754874">"Invitado"</string> + <string name="car_add_user" msgid="4067337059622483269">"Agregar usuario"</string> + <string name="car_new_user" msgid="6637442369728092473">"Usuario nuevo"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Cuando agregues un usuario nuevo, esa persona deberá configurar su espacio."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario podrá actualizar las apps de otras personas."</string> </resources> diff --git a/packages/CarSystemUI/res/values-es/strings.xml b/packages/CarSystemUI/res/values-es/strings.xml index a9d1b5fcecdb..c3cc86a21063 100644 --- a/packages/CarSystemUI/res/values-es/strings.xml +++ b/packages/CarSystemUI/res/values-es/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Mín."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Máx."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"El dispositivo Bluetooth gestiona el reconocimiento de voz"</string> + <string name="car_guest" msgid="318393171202663722">"Invitado"</string> + <string name="start_guest_session" msgid="497784785761754874">"Invitado"</string> + <string name="car_add_user" msgid="4067337059622483269">"Añadir usuario"</string> + <string name="car_new_user" msgid="6637442369728092473">"Nuevo usuario"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Cuando añades un usuario, esa persona debe configurar su espacio."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string> </resources> diff --git a/packages/CarSystemUI/res/values-et/strings.xml b/packages/CarSystemUI/res/values-et/strings.xml index e7f98c2fc2df..1bf7ce523d6a 100644 --- a/packages/CarSystemUI/res/values-et/strings.xml +++ b/packages/CarSystemUI/res/values-et/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Häältuvastust haldab nüüd ühendatud Bluetoothi seade"</string> + <string name="car_guest" msgid="318393171202663722">"Külaline"</string> + <string name="start_guest_session" msgid="497784785761754874">"Külaline"</string> + <string name="car_add_user" msgid="4067337059622483269">"Lisa kasutaja"</string> + <string name="car_new_user" msgid="6637442369728092473">"Uus kasutaja"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kui lisate uue kasutaja, siis peab ta seadistama oma ruumi."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Iga kasutaja saab rakendusi värskendada kõigi teiste kasutajate jaoks."</string> </resources> diff --git a/packages/CarSystemUI/res/values-eu/strings.xml b/packages/CarSystemUI/res/values-eu/strings.xml index b8dd6fd658e1..1786381e4e4d 100644 --- a/packages/CarSystemUI/res/values-eu/strings.xml +++ b/packages/CarSystemUI/res/values-eu/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Konektatutako Bluetooth bidezko gailuak kudeatzen du ahotsa ezagutzeko eginbidea"</string> + <string name="car_guest" msgid="318393171202663722">"Gonbidatua"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gonbidatua"</string> + <string name="car_add_user" msgid="4067337059622483269">"Gehitu erabiltzaile bat"</string> + <string name="car_new_user" msgid="6637442369728092473">"Erabiltzaile berria"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Erabiltzaile bat gehitzen duzunean, bere eremua konfiguratu beharko du."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Edozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string> </resources> diff --git a/packages/CarSystemUI/res/values-fa/strings.xml b/packages/CarSystemUI/res/values-fa/strings.xml index 06e401b19e04..0bd79ba2d4a0 100644 --- a/packages/CarSystemUI/res/values-fa/strings.xml +++ b/packages/CarSystemUI/res/values-fa/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"حداقل"</string> <string name="hvac_max_text" msgid="3669693372074755551">"حداکثر"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"اکنون تشخیص صدا را دستگاه بلوتوث متصل کنترل میکند"</string> + <string name="car_guest" msgid="318393171202663722">"مهمان"</string> + <string name="start_guest_session" msgid="497784785761754874">"مهمان"</string> + <string name="car_add_user" msgid="4067337059622483269">"افزودن کاربر"</string> + <string name="car_new_user" msgid="6637442369728092473">"کاربر جدید"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"وقتی کاربر جدیدی اضافه میکنید، آن فرد باید فضای خود را تنظیم کند."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"هر کاربری میتواند برنامهها را برای همه کاربران دیگر بهروزرسانی کند."</string> </resources> diff --git a/packages/CarSystemUI/res/values-fi/strings.xml b/packages/CarSystemUI/res/values-fi/strings.xml index 3476db7ea3fd..7aa5a5467f65 100644 --- a/packages/CarSystemUI/res/values-fi/strings.xml +++ b/packages/CarSystemUI/res/values-fi/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Alin"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Ylin"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Äänentunnistus tehdään nyt yhdistetyllä Bluetooth-laitteella"</string> + <string name="car_guest" msgid="318393171202663722">"Vieras"</string> + <string name="start_guest_session" msgid="497784785761754874">"Vieras"</string> + <string name="car_add_user" msgid="4067337059622483269">"Lisää käyttäjä"</string> + <string name="car_new_user" msgid="6637442369728092473">"Uusi käyttäjä"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kun lisäät uuden käyttäjän, hänen on valittava oman tilansa asetukset."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Kaikki käyttäjät voivat päivittää muiden käyttäjien sovelluksia."</string> </resources> diff --git a/packages/CarSystemUI/res/values-fr-rCA/strings.xml b/packages/CarSystemUI/res/values-fr-rCA/strings.xml index c1ee70119b70..22b4409494c6 100644 --- a/packages/CarSystemUI/res/values-fr-rCA/strings.xml +++ b/packages/CarSystemUI/res/values-fr-rCA/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"La reconn. voc. est gérée par l\'appareil Bluetooth connecté"</string> + <string name="car_guest" msgid="318393171202663722">"Invité"</string> + <string name="start_guest_session" msgid="497784785761754874">"Invité"</string> + <string name="car_add_user" msgid="4067337059622483269">"Ajouter un utilisateur"</string> + <string name="car_new_user" msgid="6637442369728092473">"Nouvel utilisateur"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Tout utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string> </resources> diff --git a/packages/CarSystemUI/res/values-fr/strings.xml b/packages/CarSystemUI/res/values-fr/strings.xml index 3bfdef1092f2..b28c6204d588 100644 --- a/packages/CarSystemUI/res/values-fr/strings.xml +++ b/packages/CarSystemUI/res/values-fr/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"L\'appareil Bluetooth connecté gère la reconnaissance vocale"</string> + <string name="car_guest" msgid="318393171202663722">"Invité"</string> + <string name="start_guest_session" msgid="497784785761754874">"Invité"</string> + <string name="car_add_user" msgid="4067337059622483269">"Ajouter un utilisateur"</string> + <string name="car_new_user" msgid="6637442369728092473">"Nouvel utilisateur"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"N\'importe quel utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string> </resources> diff --git a/packages/CarSystemUI/res/values-gl/strings.xml b/packages/CarSystemUI/res/values-gl/strings.xml index c8d6622b79e8..d2178ab26746 100644 --- a/packages/CarSystemUI/res/values-gl/strings.xml +++ b/packages/CarSystemUI/res/values-gl/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Mín."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Máx."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"O dispositivo Bluetooth xestionará o recoñecemento de voz"</string> + <string name="car_guest" msgid="318393171202663722">"Convidado"</string> + <string name="start_guest_session" msgid="497784785761754874">"Convidado"</string> + <string name="car_add_user" msgid="4067337059622483269">"Engadir usuario"</string> + <string name="car_new_user" msgid="6637442369728092473">"Novo usuario"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Cando engadas un novo usuario, este deberá configurar o seu espazo."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Calquera usuario pode actualizar as aplicacións para o resto dos usuarios."</string> </resources> diff --git a/packages/CarSystemUI/res/values-hi/strings.xml b/packages/CarSystemUI/res/values-hi/strings.xml index e966acccca96..3913f277dd5a 100644 --- a/packages/CarSystemUI/res/values-hi/strings.xml +++ b/packages/CarSystemUI/res/values-hi/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"कम से कम"</string> <string name="hvac_max_text" msgid="3669693372074755551">"ज़्यादा से ज़्यादा"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"अब आवाज़ पहचानने का काम, कनेक्ट किए गए ब्लूटूथ डिवाइस करते हैं"</string> + <string name="car_guest" msgid="318393171202663722">"मेहमान प्रोफ़ाइल"</string> + <string name="start_guest_session" msgid="497784785761754874">"मेहमान सेशन शुरू करें"</string> + <string name="car_add_user" msgid="4067337059622483269">"उपयोगकर्ता जोड़ें"</string> + <string name="car_new_user" msgid="6637442369728092473">"नया उपयोगकर्ता"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"जब आप कोई नया उपयोगकर्ता जोड़ते हैं, तब उसे अपनी जगह सेट करनी होती है."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"कोई भी उपयोगकर्ता, बाकी सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है."</string> </resources> diff --git a/packages/CarSystemUI/res/values-hr/strings.xml b/packages/CarSystemUI/res/values-hr/strings.xml index 51b1943420a5..befdbe9a3acb 100644 --- a/packages/CarSystemUI/res/values-hr/strings.xml +++ b/packages/CarSystemUI/res/values-hr/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Prepoznavanjem glasa rukuje se s povezanog Bluetooth uređaja"</string> + <string name="car_guest" msgid="318393171202663722">"Gost"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gost"</string> + <string name="car_add_user" msgid="4067337059622483269">"Dodajte korisnika"</string> + <string name="car_new_user" msgid="6637442369728092473">"Novi korisnik"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kada dodate novog korisnika, ta osoba mora postaviti vlastiti prostor."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Svaki korisnik može ažurirati aplikacije za ostale korisnike."</string> </resources> diff --git a/packages/CarSystemUI/res/values-hu/strings.xml b/packages/CarSystemUI/res/values-hu/strings.xml index 3613da7c8ebe..bd1e6dc735c7 100644 --- a/packages/CarSystemUI/res/values-hu/strings.xml +++ b/packages/CarSystemUI/res/values-hu/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"A hangfelismerést a csatlakoztatott Bluetooth-eszköz kezeli"</string> + <string name="car_guest" msgid="318393171202663722">"Vendég"</string> + <string name="start_guest_session" msgid="497784785761754874">"Vendég"</string> + <string name="car_add_user" msgid="4067337059622483269">"Felhasználó hozzáadása"</string> + <string name="car_new_user" msgid="6637442369728092473">"Új felhasználó"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ha új felhasználót ad hozzá, az illetőnek be kell állítania saját felületét."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Bármely felhasználó frissítheti az alkalmazásokat az összes felhasználó számára."</string> </resources> diff --git a/packages/CarSystemUI/res/values-hy/strings.xml b/packages/CarSystemUI/res/values-hy/strings.xml index 3850f70f6087..048d44af7973 100644 --- a/packages/CarSystemUI/res/values-hy/strings.xml +++ b/packages/CarSystemUI/res/values-hy/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Նվազ․"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Առավ․"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Ձայնի ճանաչումը մշակվում է միացված Bluetooth սարքի կողմից"</string> + <string name="car_guest" msgid="318393171202663722">"Հյուր"</string> + <string name="start_guest_session" msgid="497784785761754874">"Հյուրի ռեժիմ"</string> + <string name="car_add_user" msgid="4067337059622483269">"Ավելացնել օգտատեր"</string> + <string name="car_new_user" msgid="6637442369728092473">"Նոր օգտատեր"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Երբ դուք նոր օգտատեր եք ավելացնում, նա պետք է կարգավորի իր պրոֆիլը։"</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Ցանկացած օգտատեր կարող է թարմացնել հավելվածները բոլոր մյուս հաշիվների համար։"</string> </resources> diff --git a/packages/CarSystemUI/res/values-in/strings.xml b/packages/CarSystemUI/res/values-in/strings.xml index c702bdb69093..d6d7cfb8be79 100644 --- a/packages/CarSystemUI/res/values-in/strings.xml +++ b/packages/CarSystemUI/res/values-in/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Pengenalan suara ditangani perangkat Bluetooth terhubung"</string> + <string name="car_guest" msgid="318393171202663722">"Tamu"</string> + <string name="start_guest_session" msgid="497784785761754874">"Tamu"</string> + <string name="car_add_user" msgid="4067337059622483269">"Tambahkan Pengguna"</string> + <string name="car_new_user" msgid="6637442369728092473">"Pengguna Baru"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruangnya sendiri."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Setiap pengguna dapat mengupdate aplikasi untuk semua pengguna lain."</string> </resources> diff --git a/packages/CarSystemUI/res/values-is/strings.xml b/packages/CarSystemUI/res/values-is/strings.xml index 3ca6f3048f06..2b205b86403c 100644 --- a/packages/CarSystemUI/res/values-is/strings.xml +++ b/packages/CarSystemUI/res/values-is/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Lágm."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Hám."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Raddgreiningu er nú stjórnað af tengdu Bluetooth-tæki"</string> + <string name="car_guest" msgid="318393171202663722">"Gestur"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gestur"</string> + <string name="car_add_user" msgid="4067337059622483269">"Bæta notanda við"</string> + <string name="car_new_user" msgid="6637442369728092473">"Nýr notandi"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Þegar þú bætir nýjum notanda við þarf viðkomandi að setja upp sitt eigið svæði."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Allir notendur geta uppfært forrit fyrir alla aðra notendur."</string> </resources> diff --git a/packages/CarSystemUI/res/values-it/strings.xml b/packages/CarSystemUI/res/values-it/strings.xml index 54a4e1c240ba..707f2f4bc642 100644 --- a/packages/CarSystemUI/res/values-it/strings.xml +++ b/packages/CarSystemUI/res/values-it/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Riconoscimento vocale gestito da dispos. Bluetooth connesso"</string> + <string name="car_guest" msgid="318393171202663722">"Ospite"</string> + <string name="start_guest_session" msgid="497784785761754874">"Ospite"</string> + <string name="car_add_user" msgid="4067337059622483269">"Aggiungi utente"</string> + <string name="car_new_user" msgid="6637442369728092473">"Nuovo utente"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Il nuovo utente, una volta aggiunto, dovrà configurare il suo spazio."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualsiasi utente può aggiornare le app per tutti gli altri."</string> </resources> diff --git a/packages/CarSystemUI/res/values-iw/strings.xml b/packages/CarSystemUI/res/values-iw/strings.xml new file mode 100644 index 000000000000..93f2401d51b8 --- /dev/null +++ b/packages/CarSystemUI/res/values-iw/strings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="hvac_min_text" msgid="8167124789068494624">"מינ\'"</string> + <string name="hvac_max_text" msgid="3669693372074755551">"מקס\'"</string> + <string name="voice_recognition_toast" msgid="1149934534584052842">"הזיהוי הקולי מתבצע עכשיו במכשיר Bluetooth מחובר"</string> + <string name="car_guest" msgid="318393171202663722">"אורח"</string> + <string name="start_guest_session" msgid="497784785761754874">"אורח"</string> + <string name="car_add_user" msgid="4067337059622483269">"הוספת משתמש"</string> + <string name="car_new_user" msgid="6637442369728092473">"משתמש חדש"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"בעת הוספת משתמש חדש, על משתמש זה להגדיר את המרחב שלו."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"כל משתמש יכול לעדכן אפליקציות לכל שאר המשתמשים."</string> +</resources> diff --git a/packages/CarSystemUI/res/values-ja/strings.xml b/packages/CarSystemUI/res/values-ja/strings.xml index ab20a2050545..85bd0bf64f7f 100644 --- a/packages/CarSystemUI/res/values-ja/strings.xml +++ b/packages/CarSystemUI/res/values-ja/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"最小"</string> <string name="hvac_max_text" msgid="3669693372074755551">"最大"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Bluetooth 接続デバイスで音声認識が処理されるようになりました"</string> + <string name="car_guest" msgid="318393171202663722">"ゲスト"</string> + <string name="start_guest_session" msgid="497784785761754874">"ゲスト"</string> + <string name="car_add_user" msgid="4067337059622483269">"ユーザーを追加"</string> + <string name="car_new_user" msgid="6637442369728092473">"新しいユーザー"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"新しいユーザーを追加したら、そのユーザーは自分のスペースをセットアップする必要があります。"</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"どのユーザーも他のすべてのユーザーに代わってアプリを更新できます。"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ka/strings.xml b/packages/CarSystemUI/res/values-ka/strings.xml index 94e25ea08598..0e67f2ae8a77 100644 --- a/packages/CarSystemUI/res/values-ka/strings.xml +++ b/packages/CarSystemUI/res/values-ka/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"მინ"</string> <string name="hvac_max_text" msgid="3669693372074755551">"მაქს"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"ხმის ამოცნობა დამუშავდება დაკავშირებული Bluetooth-მოწყობილობით"</string> + <string name="car_guest" msgid="318393171202663722">"სტუმარი"</string> + <string name="start_guest_session" msgid="497784785761754874">"სტუმარი"</string> + <string name="car_add_user" msgid="4067337059622483269">"მომხმარებლის დამატება"</string> + <string name="car_new_user" msgid="6637442369728092473">"ახალი მომხმარებელი"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"ახალი მომხმარებლის დამატებისას, ამ მომხმარებელს საკუთარი სივრცის გამართვა მოუწევს."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"ნებისმიერ მომხმარებელს შეუძლია აპები ყველა სხვა მომხმარებლისათვის განაახლოს."</string> </resources> diff --git a/packages/CarSystemUI/res/values-kk/strings.xml b/packages/CarSystemUI/res/values-kk/strings.xml new file mode 100644 index 000000000000..94a192ee8df4 --- /dev/null +++ b/packages/CarSystemUI/res/values-kk/strings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string> + <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string> + <string name="voice_recognition_toast" msgid="1149934534584052842">"Дауысты тану үшін Bluetooth құрылғысы пайдаланылады."</string> + <string name="car_guest" msgid="318393171202663722">"Қонақ"</string> + <string name="start_guest_session" msgid="497784785761754874">"Қонақ"</string> + <string name="car_add_user" msgid="4067337059622483269">"Пайдаланушыны енгізу"</string> + <string name="car_new_user" msgid="6637442369728092473">"Жаңа пайдаланушы"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Енгізілген жаңа пайдаланушы өз профилін реттеуі керек."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Кез келген пайдаланушы қолданбаларды басқа пайдаланушылар үшін жаңарта алады."</string> +</resources> diff --git a/packages/CarSystemUI/res/values-km/strings.xml b/packages/CarSystemUI/res/values-km/strings.xml index e865fc70d75d..47b659f47f76 100644 --- a/packages/CarSystemUI/res/values-km/strings.xml +++ b/packages/CarSystemUI/res/values-km/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"អប្បបរមា"</string> <string name="hvac_max_text" msgid="3669693372074755551">"អតិបរិមា"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"ឥឡូវនេះ ការសម្គាល់សំឡេងត្រូវបានចាត់ចែងដោយឧបករណ៍ដែលបានភ្ជាប់ប៊្លូធូស"</string> + <string name="car_guest" msgid="318393171202663722">"ភ្ញៀវ"</string> + <string name="start_guest_session" msgid="497784785761754874">"ភ្ញៀវ"</string> + <string name="car_add_user" msgid="4067337059622483269">"បញ្ចូលអ្នកប្រើប្រាស់"</string> + <string name="car_new_user" msgid="6637442369728092473">"អ្នកប្រើប្រាស់ថ្មី"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"នៅពេលដែលអ្នកបញ្ចូលអ្នកប្រើប្រាស់ថ្មី បុគ្គលនោះត្រូវតែរៀបចំទំហំផ្ទុករបស់គេ។"</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"អ្នកប្រើប្រាស់ណាក៏អាចដំឡើងកំណែកម្មវិធីសម្រាប់អ្នកប្រើប្រាស់ទាំងអស់ផ្សេងទៀតបានដែរ។"</string> </resources> diff --git a/packages/CarSystemUI/res/values-kn/strings.xml b/packages/CarSystemUI/res/values-kn/strings.xml index 0d425bbebdf5..50e1721874ca 100644 --- a/packages/CarSystemUI/res/values-kn/strings.xml +++ b/packages/CarSystemUI/res/values-kn/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"ಕನಿಷ್ಠ"</string> <string name="hvac_max_text" msgid="3669693372074755551">"ಗರಿಷ್ಠ"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"ಇದೀಗ ಕನೆಕ್ಟ್ ಆದ ಬ್ಲೂಟೂತ್ ಸಾಧನ ಧ್ವನಿ ಗುರುತಿಸುವಿಕೆ ನಿರ್ವಹಿಸಿದೆ"</string> + <string name="car_guest" msgid="318393171202663722">"ಅತಿಥಿ"</string> + <string name="start_guest_session" msgid="497784785761754874">"ಅತಿಥಿ"</string> + <string name="car_add_user" msgid="4067337059622483269">"ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ"</string> + <string name="car_new_user" msgid="6637442369728092473">"ಹೊಸ ಬಳಕೆದಾರ"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"ನೀವು ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಸೆಟಪ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"ಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಆ್ಯಪ್ಗಳನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಬಹುದು."</string> </resources> diff --git a/packages/CarSystemUI/res/values-ko/strings.xml b/packages/CarSystemUI/res/values-ko/strings.xml index 695ee3f9cda7..75b16a821ea1 100644 --- a/packages/CarSystemUI/res/values-ko/strings.xml +++ b/packages/CarSystemUI/res/values-ko/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"최소"</string> <string name="hvac_max_text" msgid="3669693372074755551">"최대"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"이제 연결된 블루투스 기기에서 음성 인식이 처리됩니다."</string> + <string name="car_guest" msgid="318393171202663722">"게스트"</string> + <string name="start_guest_session" msgid="497784785761754874">"게스트"</string> + <string name="car_add_user" msgid="4067337059622483269">"사용자 추가"</string> + <string name="car_new_user" msgid="6637442369728092473">"신규 사용자"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"추가된 신규 사용자는 자신만의 공간을 설정해야 합니다."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"누구나 다른 모든 사용자를 위해 앱을 업데이트할 수 있습니다."</string> </resources> diff --git a/packages/CarSystemUI/res/values-ky/strings.xml b/packages/CarSystemUI/res/values-ky/strings.xml new file mode 100644 index 000000000000..e9da09d03456 --- /dev/null +++ b/packages/CarSystemUI/res/values-ky/strings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string> + <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string> + <string name="voice_recognition_toast" msgid="1149934534584052842">"Үндү эми туташкан Bluetooth түзмөгү менен тааныса болот"</string> + <string name="car_guest" msgid="318393171202663722">"Конок"</string> + <string name="start_guest_session" msgid="497784785761754874">"Конок"</string> + <string name="car_add_user" msgid="4067337059622483269">"Колдонуучу кошуу"</string> + <string name="car_new_user" msgid="6637442369728092473">"Жаңы колдонуучу"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Жаңы колдонуучу кошулганда, ал өзүнүн профилин жөндөп алышы керек."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Колдонмолорду бир колдонуучу калган бардык колдонуучулар үчүн да жаңырта алат."</string> +</resources> diff --git a/packages/CarSystemUI/res/values-lo/strings.xml b/packages/CarSystemUI/res/values-lo/strings.xml new file mode 100644 index 000000000000..1721377c11e1 --- /dev/null +++ b/packages/CarSystemUI/res/values-lo/strings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="hvac_min_text" msgid="8167124789068494624">"ນທ"</string> + <string name="hvac_max_text" msgid="3669693372074755551">"ສູງສຸດ"</string> + <string name="voice_recognition_toast" msgid="1149934534584052842">"ການຈຳແນກສຽງເວົ້າດຽວນີ້ຈັດການໂດຍອຸປະກອນ Bluetooth ທີ່ເຊື່ອມຕໍ່"</string> + <string name="car_guest" msgid="318393171202663722">"ແຂກ"</string> + <string name="start_guest_session" msgid="497784785761754874">"ແຂກ"</string> + <string name="car_add_user" msgid="4067337059622483269">"ເພີ່ມຜູ້ໃຊ້"</string> + <string name="car_new_user" msgid="6637442369728092473">"ຜູ້ໃຊ້ໃໝ່"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"ເມື່ອທ່ານເພີ່ມຜູ້ໃຊ້ໃໝ່, ບຸກຄົນນັ້ນຈຳເປັນຕ້ອງຕັ້ງຄ່າພື້ນທີ່ຂອງເຂົາເຈົ້າ."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"ຜູ້ໃຊ້ຕ່າງໆສາມາດອັບເດດແອັບສຳລັບຜູ້ໃຊ້ອື່ນທັງໝົດໄດ້."</string> +</resources> diff --git a/packages/CarSystemUI/res/values-lt/strings.xml b/packages/CarSystemUI/res/values-lt/strings.xml index 80c63d9c9831..d504c1265ad8 100644 --- a/packages/CarSystemUI/res/values-lt/strings.xml +++ b/packages/CarSystemUI/res/values-lt/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Didž."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Balso atpažinimą dabar tvarko susietas „Bluetooth“ įrenginys"</string> + <string name="car_guest" msgid="318393171202663722">"Svečias"</string> + <string name="start_guest_session" msgid="497784785761754874">"Svečias"</string> + <string name="car_add_user" msgid="4067337059622483269">"Pridėti naudotoją"</string> + <string name="car_new_user" msgid="6637442369728092473">"Naujas naudotojas"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kai pridedate naują naudotoją, šis asmuo turi nustatyti savo vietą."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Bet kuris naudotojas gali atnaujinti visų kitų naudotojų programas."</string> </resources> diff --git a/packages/CarSystemUI/res/values-lv/strings.xml b/packages/CarSystemUI/res/values-lv/strings.xml index f63023c3ff49..8a0be70f54ab 100644 --- a/packages/CarSystemUI/res/values-lv/strings.xml +++ b/packages/CarSystemUI/res/values-lv/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Balss atpazīšanu tagad nodrošina pievienotā Bluetooth ierīce"</string> + <string name="car_guest" msgid="318393171202663722">"Viesis"</string> + <string name="start_guest_session" msgid="497784785761754874">"Viesis"</string> + <string name="car_add_user" msgid="4067337059622483269">"Pievienot lietotāju"</string> + <string name="car_new_user" msgid="6637442369728092473">"Jauns lietotājs"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kad pievienojat jaunu lietotāju, viņam ir jāizveido savs profils."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Ikviens lietotājs var atjaunināt lietotnes visu lietotāju vārdā."</string> </resources> diff --git a/packages/CarSystemUI/res/values-mk/strings.xml b/packages/CarSystemUI/res/values-mk/strings.xml index fccd94cd0070..63cea06f7371 100644 --- a/packages/CarSystemUI/res/values-mk/strings.xml +++ b/packages/CarSystemUI/res/values-mk/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Поврзаниот уред со Bluetooth управува со препознавањето глас"</string> + <string name="car_guest" msgid="318393171202663722">"Гостин"</string> + <string name="start_guest_session" msgid="497784785761754874">"Гостин"</string> + <string name="car_add_user" msgid="4067337059622483269">"Додај корисник"</string> + <string name="car_new_user" msgid="6637442369728092473">"Нов корисник"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Кога додавате нов корисник, тоа лице треба да го постави својот простор."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Секој корисник може да ажурира апликации за сите други корисници."</string> </resources> diff --git a/packages/CarSystemUI/res/values-ml/strings.xml b/packages/CarSystemUI/res/values-ml/strings.xml index b30e27410a01..f7934d112f95 100644 --- a/packages/CarSystemUI/res/values-ml/strings.xml +++ b/packages/CarSystemUI/res/values-ml/strings.xml @@ -20,4 +20,16 @@ <string name="hvac_min_text" msgid="8167124789068494624">"മിനിമം"</string> <string name="hvac_max_text" msgid="3669693372074755551">"മാക്സിമം"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"കണക്റ്റ് ചെയ്ത Bluetooth ഉപകരണം വഴി ഇപ്പോൾ വോയ്സ് തിരിച്ചറിയൽ കെെകാര്യം ചെയ്യുന്നു"</string> + <!-- no translation found for car_guest (318393171202663722) --> + <skip /> + <!-- no translation found for start_guest_session (497784785761754874) --> + <skip /> + <!-- no translation found for car_add_user (4067337059622483269) --> + <skip /> + <!-- no translation found for car_new_user (6637442369728092473) --> + <skip /> + <!-- no translation found for user_add_user_message_setup (1035578846007352323) --> + <skip /> + <!-- no translation found for user_add_user_message_update (7061671307004867811) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-mn/strings.xml b/packages/CarSystemUI/res/values-mn/strings.xml index e04ff9d0d952..bae5c64f8cdf 100644 --- a/packages/CarSystemUI/res/values-mn/strings.xml +++ b/packages/CarSystemUI/res/values-mn/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Бага"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Их"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Одоо дуугаар танихыг холбогдсон Bluetooth төхөөрөмж удирдана"</string> + <string name="car_guest" msgid="318393171202663722">"Зочин"</string> + <string name="start_guest_session" msgid="497784785761754874">"Зочин"</string> + <string name="car_add_user" msgid="4067337059622483269">"Хэрэглэгч нэмэх"</string> + <string name="car_new_user" msgid="6637442369728092473">"Шинэ хэрэглэгч"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Та шинэ хэрэглэгч нэмэх үед тухайн хэрэглэгч хувийн орон зайгаа тохируулах шаардлагатай."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Бусад бүх хэрэглэгчийн аппыг дурын хэрэглэгч шинэчлэх боломжтой."</string> </resources> diff --git a/packages/CarSystemUI/res/values-ms/strings.xml b/packages/CarSystemUI/res/values-ms/strings.xml index 0d153fa8116f..868a0605b433 100644 --- a/packages/CarSystemUI/res/values-ms/strings.xml +++ b/packages/CarSystemUI/res/values-ms/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Pengecaman suara kini dikendalikan peranti Bluetooth tersmbg"</string> + <string name="car_guest" msgid="318393171202663722">"Tetamu"</string> + <string name="start_guest_session" msgid="497784785761754874">"Tetamu"</string> + <string name="car_add_user" msgid="4067337059622483269">"Tambah Pengguna"</string> + <string name="car_new_user" msgid="6637442369728092473">"Pengguna Baharu"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Apabila anda menambahkan pengguna baharu, orang itu perlu menyediakan ruang mereka."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Mana-mana pengguna boleh mengemas kini apl untuk semua pengguna lain."</string> </resources> diff --git a/packages/CarSystemUI/res/values-my/strings.xml b/packages/CarSystemUI/res/values-my/strings.xml index a1817ed96777..231b41f06aab 100644 --- a/packages/CarSystemUI/res/values-my/strings.xml +++ b/packages/CarSystemUI/res/values-my/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"နိမ့်"</string> <string name="hvac_max_text" msgid="3669693372074755551">"မြင့်"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"ချိတ်ထားသော ဘလူးတုသ်စက်ဖြင့် အသံမှတ်သားမှုကို ထိန်းချုပ်သည်"</string> + <string name="car_guest" msgid="318393171202663722">"ဧည့်သည်"</string> + <string name="start_guest_session" msgid="497784785761754874">"ဧည့်သည်"</string> + <string name="car_add_user" msgid="4067337059622483269">"အသုံးပြုသူ ထည့်ရန်"</string> + <string name="car_new_user" msgid="6637442369728092473">"အသုံးပြုသူ အသစ်"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"အသုံးပြုသူအသစ် ထည့်သည့်အခါ ထိုသူသည် မိမိ၏ နေရာကို စနစ်ထည့်သွင်းရပါမည်။"</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"မည်သူမဆို အသုံးပြုသူအားလုံးအတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်နိုင်သည်။"</string> </resources> diff --git a/packages/CarSystemUI/res/values-nb/strings.xml b/packages/CarSystemUI/res/values-nb/strings.xml index b84e4ed55d87..9141cfc11d2a 100644 --- a/packages/CarSystemUI/res/values-nb/strings.xml +++ b/packages/CarSystemUI/res/values-nb/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Talegjenkjenning håndteres nå av tilkoblet Bluetooth-enhet"</string> + <string name="car_guest" msgid="318393171202663722">"Gjest"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gjest"</string> + <string name="car_add_user" msgid="4067337059622483269">"Legg til bruker"</string> + <string name="car_new_user" msgid="6637442369728092473">"Ny bruker"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Når du legger til en ny bruker, må vedkommende konfigurere sitt eget område."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Alle brukere kan oppdatere apper for alle andre brukere."</string> </resources> diff --git a/packages/CarSystemUI/res/values-ne/strings.xml b/packages/CarSystemUI/res/values-ne/strings.xml new file mode 100644 index 000000000000..b17c8b44b6ba --- /dev/null +++ b/packages/CarSystemUI/res/values-ne/strings.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="hvac_min_text" msgid="8167124789068494624">"न्यूनतम"</string> + <string name="hvac_max_text" msgid="3669693372074755551">"अधिकतम"</string> + <string name="voice_recognition_toast" msgid="1149934534584052842">"अब ब्लुटुथ मार्फत जोडिएको यन्त्रले आवाज पहिचान गर्ने कार्य सम्हाल्छ"</string> + <!-- no translation found for car_guest (318393171202663722) --> + <skip /> + <!-- no translation found for start_guest_session (497784785761754874) --> + <skip /> + <!-- no translation found for car_add_user (4067337059622483269) --> + <skip /> + <!-- no translation found for car_new_user (6637442369728092473) --> + <skip /> + <!-- no translation found for user_add_user_message_setup (1035578846007352323) --> + <skip /> + <!-- no translation found for user_add_user_message_update (7061671307004867811) --> + <skip /> +</resources> diff --git a/packages/CarSystemUI/res/values-nl/strings.xml b/packages/CarSystemUI/res/values-nl/strings.xml index 17395896ba21..5ba7ce41b37c 100644 --- a/packages/CarSystemUI/res/values-nl/strings.xml +++ b/packages/CarSystemUI/res/values-nl/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Spraakherkenning actief via een verbonden bluetooth-apparaat"</string> + <string name="car_guest" msgid="318393171202663722">"Gast"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gast"</string> + <string name="car_add_user" msgid="4067337059622483269">"Gebruiker toevoegen"</string> + <string name="car_new_user" msgid="6637442369728092473">"Nieuwe gebruiker"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Als je een nieuwe gebruiker toevoegt, moet die persoon een eigen profiel instellen."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Elke gebruiker kan apps updaten voor alle andere gebruikers"</string> </resources> diff --git a/packages/CarSystemUI/res/values-or/strings.xml b/packages/CarSystemUI/res/values-or/strings.xml new file mode 100644 index 000000000000..4d1a6ac99b61 --- /dev/null +++ b/packages/CarSystemUI/res/values-or/strings.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="hvac_min_text" msgid="8167124789068494624">"ସର୍ବନିମ୍ନ"</string> + <string name="hvac_max_text" msgid="3669693372074755551">"ସର୍ବାଧିକ"</string> + <string name="voice_recognition_toast" msgid="1149934534584052842">"ଭଏସ ଚିହ୍ନଟକରଣ ଏବେ ସଂଯୁକ୍ତ ଥିବା ବ୍ଲୁଟୁଥ ଡିଭାଇସ ଦ୍ୱାରା ପରିଚାଳିତ"</string> + <!-- no translation found for car_guest (318393171202663722) --> + <skip /> + <!-- no translation found for start_guest_session (497784785761754874) --> + <skip /> + <!-- no translation found for car_add_user (4067337059622483269) --> + <skip /> + <!-- no translation found for car_new_user (6637442369728092473) --> + <skip /> + <!-- no translation found for user_add_user_message_setup (1035578846007352323) --> + <skip /> + <!-- no translation found for user_add_user_message_update (7061671307004867811) --> + <skip /> +</resources> diff --git a/packages/CarSystemUI/res/values-pa/strings.xml b/packages/CarSystemUI/res/values-pa/strings.xml index cc6fbe50a8e6..8184c2cac008 100644 --- a/packages/CarSystemUI/res/values-pa/strings.xml +++ b/packages/CarSystemUI/res/values-pa/strings.xml @@ -20,4 +20,16 @@ <string name="hvac_min_text" msgid="8167124789068494624">"ਨਿਊਨਤਮ"</string> <string name="hvac_max_text" msgid="3669693372074755551">"ਅਧਿਕਤਮ"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"ਅਵਾਜ਼ ਦੀ ਪਛਾਣ ਨੂੰ ਹੁਣ ਕਨੈਕਟ ਕੀਤਾ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸ ਸੰਭਾਲਦਾ ਹੈ"</string> + <!-- no translation found for car_guest (318393171202663722) --> + <skip /> + <!-- no translation found for start_guest_session (497784785761754874) --> + <skip /> + <!-- no translation found for car_add_user (4067337059622483269) --> + <skip /> + <!-- no translation found for car_new_user (6637442369728092473) --> + <skip /> + <!-- no translation found for user_add_user_message_setup (1035578846007352323) --> + <skip /> + <!-- no translation found for user_add_user_message_update (7061671307004867811) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-pl/strings.xml b/packages/CarSystemUI/res/values-pl/strings.xml index 1b083d300713..35d735b38dac 100644 --- a/packages/CarSystemUI/res/values-pl/strings.xml +++ b/packages/CarSystemUI/res/values-pl/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Rozpoznawanie mowy przez połączone urządzenie Bluetooth"</string> + <string name="car_guest" msgid="318393171202663722">"Gość"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gość"</string> + <string name="car_add_user" msgid="4067337059622483269">"Dodaj użytkownika"</string> + <string name="car_new_user" msgid="6637442369728092473">"Nowy użytkownik"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Gdy dodasz nowego użytkownika, musi on skonfigurować swój profil."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Każdy użytkownik może aktualizować aplikacje wszystkich innych użytkowników."</string> </resources> diff --git a/packages/CarSystemUI/res/values-pt-rPT/strings.xml b/packages/CarSystemUI/res/values-pt-rPT/strings.xml index d6ba00843d20..7b0ee14e9a94 100644 --- a/packages/CarSystemUI/res/values-pt-rPT/strings.xml +++ b/packages/CarSystemUI/res/values-pt-rPT/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Mín."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Máx."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Reconhecimento de voz agora através do disp. Bluetooth lig."</string> + <string name="car_guest" msgid="318393171202663722">"Convidado"</string> + <string name="start_guest_session" msgid="497784785761754874">"Convidado"</string> + <string name="car_add_user" msgid="4067337059622483269">"Adicionar utilizador"</string> + <string name="car_new_user" msgid="6637442369728092473">"Novo utilizador"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualquer utilizador pode atualizar apps para todos os outros utilizadores."</string> </resources> diff --git a/packages/CarSystemUI/res/values-pt/strings.xml b/packages/CarSystemUI/res/values-pt/strings.xml index ded1624a83d4..fab603d2b389 100644 --- a/packages/CarSystemUI/res/values-pt/strings.xml +++ b/packages/CarSystemUI/res/values-pt/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Mín"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Máx"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Reconhecimento de voz com dispositivo Bluetooth conectado"</string> + <string name="car_guest" msgid="318393171202663722">"Convidado"</string> + <string name="start_guest_session" msgid="497784785761754874">"Convidado"</string> + <string name="car_add_user" msgid="4067337059622483269">"Adicionar usuário"</string> + <string name="car_new_user" msgid="6637442369728092473">"Novo usuário"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quando você adiciona um usuário novo, essa pessoa precisa configurar o espaço dela."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualquer usuário pode atualizar apps para os demais usuários."</string> </resources> diff --git a/packages/CarSystemUI/res/values-ro/strings.xml b/packages/CarSystemUI/res/values-ro/strings.xml index bb0f86697b67..adf83a323905 100644 --- a/packages/CarSystemUI/res/values-ro/strings.xml +++ b/packages/CarSystemUI/res/values-ro/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Recunoașterea vocală acum gestionată de dispozitivul Bluetooth conectat"</string> + <string name="car_guest" msgid="318393171202663722">"Invitat"</string> + <string name="start_guest_session" msgid="497784785761754874">"Invitat"</string> + <string name="car_add_user" msgid="4067337059622483269">"Adăugați un utilizator"</string> + <string name="car_new_user" msgid="6637442369728092473">"Utilizator nou"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Când adăugați un utilizator nou, acesta trebuie să-și configureze spațiul."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Orice utilizator poate actualiza aplicațiile pentru toți ceilalți utilizatori."</string> </resources> diff --git a/packages/CarSystemUI/res/values-ru/strings.xml b/packages/CarSystemUI/res/values-ru/strings.xml index 6b6fdc9e6a97..69ee939de3db 100644 --- a/packages/CarSystemUI/res/values-ru/strings.xml +++ b/packages/CarSystemUI/res/values-ru/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Для распознавания речи используется Bluetooth-устройство."</string> + <string name="car_guest" msgid="318393171202663722">"Гость"</string> + <string name="start_guest_session" msgid="497784785761754874">"Гость"</string> + <string name="car_add_user" msgid="4067337059622483269">"Добавить пользователя"</string> + <string name="car_new_user" msgid="6637442369728092473">"Новый пользователь"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Когда вы добавите пользователя, ему потребуется настроить профиль."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Любой пользователь устройства может обновлять приложения для всех аккаунтов."</string> </resources> diff --git a/packages/CarSystemUI/res/values-si/strings.xml b/packages/CarSystemUI/res/values-si/strings.xml index 08baac31c478..061d4ed685e1 100644 --- a/packages/CarSystemUI/res/values-si/strings.xml +++ b/packages/CarSystemUI/res/values-si/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"අවම"</string> <string name="hvac_max_text" msgid="3669693372074755551">"උපරිම"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"හඬ හැඳුනුම දැන් සම්බන්ධ බ්ලූටූත් උපාංගය මගින් හසුරුවනු ලැබේ"</string> + <string name="car_guest" msgid="318393171202663722">"අමුත්තා"</string> + <string name="start_guest_session" msgid="497784785761754874">"අමුත්තා"</string> + <string name="car_add_user" msgid="4067337059622483269">"පරිශීලක එක් කරන්න"</string> + <string name="car_new_user" msgid="6637442369728092473">"නව පරිශීලක"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"ඔබ අලුත් පරිශීලකයෙකු එක් කරන විට, එම පුද්ගලයා තමන්ගේ ඉඩ සකසා ගැනීමට අවශ්ය වේ."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"සියලුම අනෙක් පරිශීලකයින් සඳහා ඕනෑම පරිශීලකයෙකුට යෙදුම් යාවත්කාලීන කළ හැක."</string> </resources> diff --git a/packages/CarSystemUI/res/values-sk/strings.xml b/packages/CarSystemUI/res/values-sk/strings.xml index 086de1e1f8a3..619cf2914b93 100644 --- a/packages/CarSystemUI/res/values-sk/strings.xml +++ b/packages/CarSystemUI/res/values-sk/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"max."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Rozpoznávanie hlasu teraz prebieha v pripoj. zar. Bluetooth"</string> + <string name="car_guest" msgid="318393171202663722">"Hosť"</string> + <string name="start_guest_session" msgid="497784785761754874">"Hosť"</string> + <string name="car_add_user" msgid="4067337059622483269">"Pridať používateľa"</string> + <string name="car_new_user" msgid="6637442369728092473">"Nový používateľ"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Akýkoľvek používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string> </resources> diff --git a/packages/CarSystemUI/res/values-sl/strings.xml b/packages/CarSystemUI/res/values-sl/strings.xml index 8c4b5ef88234..b386591d369e 100644 --- a/packages/CarSystemUI/res/values-sl/strings.xml +++ b/packages/CarSystemUI/res/values-sl/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Najn."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Najv."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Prepoznavanje glasu zdaj izvaja povezana naprava Bluetooth"</string> + <string name="car_guest" msgid="318393171202663722">"Gost"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gost"</string> + <string name="car_add_user" msgid="4067337059622483269">"Dodaj uporabnika"</string> + <string name="car_new_user" msgid="6637442369728092473">"Nov uporabnik"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ko dodate novega uporabnika, mora ta nastaviti svoj prostor."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Vsak uporabnik lahko posodobi aplikacije za vse druge uporabnike."</string> </resources> diff --git a/packages/CarSystemUI/res/values-sr/strings.xml b/packages/CarSystemUI/res/values-sr/strings.xml index 8ea6fd2567d2..20969672eef3 100644 --- a/packages/CarSystemUI/res/values-sr/strings.xml +++ b/packages/CarSystemUI/res/values-sr/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Мин."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maкс."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Препознавањем гласа сада управља повезани Bluetooth уређај"</string> + <string name="car_guest" msgid="318393171202663722">"Гост"</string> + <string name="start_guest_session" msgid="497784785761754874">"Гост"</string> + <string name="car_add_user" msgid="4067337059622483269">"Додај корисника"</string> + <string name="car_new_user" msgid="6637442369728092473">"Нови корисник"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Када додате новог корисника, та особа треба да подеси свој простор."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Сваки корисник може да ажурира апликације за све остале кориснике."</string> </resources> diff --git a/packages/CarSystemUI/res/values-sv/strings.xml b/packages/CarSystemUI/res/values-sv/strings.xml index bd6e25f7d676..af3f5b87b853 100644 --- a/packages/CarSystemUI/res/values-sv/strings.xml +++ b/packages/CarSystemUI/res/values-sv/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Nu hanteras röstigenkänning via en anstluten Bluetooth-enhet"</string> + <string name="car_guest" msgid="318393171202663722">"Gäst"</string> + <string name="start_guest_session" msgid="497784785761754874">"Gäst"</string> + <string name="car_add_user" msgid="4067337059622483269">"Lägg till användare"</string> + <string name="car_new_user" msgid="6637442369728092473">"Ny användare"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"När du lägger till en ny användare måste den personen konfigurera sitt utrymme."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Alla användare kan uppdatera appar för andra användare."</string> </resources> diff --git a/packages/CarSystemUI/res/values-sw/strings.xml b/packages/CarSystemUI/res/values-sw/strings.xml index fbeacf6f6fce..1aa086819784 100644 --- a/packages/CarSystemUI/res/values-sw/strings.xml +++ b/packages/CarSystemUI/res/values-sw/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Chini"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Juu"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Utambuzi wa sauti sasa unashughulikiwa na kifaa kilichounganishwa cha Bluetooth"</string> + <string name="car_guest" msgid="318393171202663722">"Mgeni"</string> + <string name="start_guest_session" msgid="497784785761754874">"Mgeni"</string> + <string name="car_add_user" msgid="4067337059622483269">"Ongeza Mtumiaji"</string> + <string name="car_new_user" msgid="6637442369728092473">"Mtumiaji Mpya"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ukiongeza mtumiaji mpya, ni lazima aweke kikundi chake."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Mtumiaji yeyote anaweza kusasisha programu za watumiaji wengine."</string> </resources> diff --git a/packages/CarSystemUI/res/values-ta/strings.xml b/packages/CarSystemUI/res/values-ta/strings.xml new file mode 100644 index 000000000000..9f76f777a9d1 --- /dev/null +++ b/packages/CarSystemUI/res/values-ta/strings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="hvac_min_text" msgid="8167124789068494624">"குறைந்தபட்சம்"</string> + <string name="hvac_max_text" msgid="3669693372074755551">"அதிகபட்சம்"</string> + <string name="voice_recognition_toast" msgid="1149934534584052842">"இணைக்கப்பட்ட புளூடூத் சாதனத்தால் \'குரல் அறிதல்\' கையாளப்படுகிறது"</string> + <string name="car_guest" msgid="318393171202663722">"கெஸ்ட்"</string> + <string name="start_guest_session" msgid="497784785761754874">"கெஸ்ட்"</string> + <string name="car_add_user" msgid="4067337059622483269">"பயனரைச் சேருங்கள்"</string> + <string name="car_new_user" msgid="6637442369728092473">"புதிய பயனர்"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"புதிய பயனரைச் சேர்க்கும்போது அவர் தனக்கான சேமிப்பிடத்தை அமைக்க வேண்டும்."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"எந்தப் பயனரும் பிற பயனர்கள் சார்பாக ஆப்ஸைப் புதுப்பிக்க முடியும்."</string> +</resources> diff --git a/packages/CarSystemUI/res/values-te/strings.xml b/packages/CarSystemUI/res/values-te/strings.xml index bc853311da17..bfa586f22f22 100644 --- a/packages/CarSystemUI/res/values-te/strings.xml +++ b/packages/CarSystemUI/res/values-te/strings.xml @@ -20,4 +20,16 @@ <string name="hvac_min_text" msgid="8167124789068494624">"కని."</string> <string name="hvac_max_text" msgid="3669693372074755551">"గరి."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"నేడు వాయిస్ గుర్తింపును కనెక్ట్ అయిన బ్లూటూత్ నిర్వహిస్తోంది"</string> + <!-- no translation found for car_guest (318393171202663722) --> + <skip /> + <!-- no translation found for start_guest_session (497784785761754874) --> + <skip /> + <!-- no translation found for car_add_user (4067337059622483269) --> + <skip /> + <!-- no translation found for car_new_user (6637442369728092473) --> + <skip /> + <!-- no translation found for user_add_user_message_setup (1035578846007352323) --> + <skip /> + <!-- no translation found for user_add_user_message_update (7061671307004867811) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-th/strings.xml b/packages/CarSystemUI/res/values-th/strings.xml index e291aa21fdcb..57ac7dc72cc6 100644 --- a/packages/CarSystemUI/res/values-th/strings.xml +++ b/packages/CarSystemUI/res/values-th/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"ตอนนี้อุปกรณ์บลูทูธที่เชื่อมต่อจะจัดการการจดจำเสียง"</string> + <string name="car_guest" msgid="318393171202663722">"ผู้ใช้ชั่วคราว"</string> + <string name="start_guest_session" msgid="497784785761754874">"ผู้ใช้ชั่วคราว"</string> + <string name="car_add_user" msgid="4067337059622483269">"เพิ่มผู้ใช้"</string> + <string name="car_new_user" msgid="6637442369728092473">"ผู้ใช้ใหม่"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"เมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตนเอง"</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"ผู้ใช้ทุกคนจะอัปเดตแอปให้แก่ผู้ใช้คนอื่นๆ ได้"</string> </resources> diff --git a/packages/CarSystemUI/res/values-tl/strings.xml b/packages/CarSystemUI/res/values-tl/strings.xml index a0a38fa5c5b5..5e0af6d6c266 100644 --- a/packages/CarSystemUI/res/values-tl/strings.xml +++ b/packages/CarSystemUI/res/values-tl/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Minuto"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Max"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Hawak na ngayon ng Bluetooth device ang Pagkilala ng boses"</string> + <string name="car_guest" msgid="318393171202663722">"Bisita"</string> + <string name="start_guest_session" msgid="497784785761754874">"Bisita"</string> + <string name="car_add_user" msgid="4067337059622483269">"Magdagdag ng User"</string> + <string name="car_new_user" msgid="6637442369728092473">"Bagong User"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kapag nagdagdag ka ng bagong user, kailangang i-set up ng taong iyon ang kanyang espasyo."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Puwedeng i-update ng sinumang user ang mga app para sa lahat ng iba pang user."</string> </resources> diff --git a/packages/CarSystemUI/res/values-tr/strings.xml b/packages/CarSystemUI/res/values-tr/strings.xml index 5eaae11dd56c..7949329ba1c3 100644 --- a/packages/CarSystemUI/res/values-tr/strings.xml +++ b/packages/CarSystemUI/res/values-tr/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Min."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Artık ses tanıma, bağlı Bluetooth cihazı tarafından işleniyor"</string> + <string name="car_guest" msgid="318393171202663722">"Misafir"</string> + <string name="start_guest_session" msgid="497784785761754874">"Misafir"</string> + <string name="car_add_user" msgid="4067337059622483269">"Kullanıcı Ekle"</string> + <string name="car_new_user" msgid="6637442369728092473">"Yeni Kullanıcı"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Yeni kullanıcı eklediğinizde, bu kişinin alanını ayarlaması gerekir."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Herhangi bir kullanıcı, diğer tüm kullanıcılar için uygulamaları güncelleyebilir."</string> </resources> diff --git a/packages/CarSystemUI/res/values-uk/strings.xml b/packages/CarSystemUI/res/values-uk/strings.xml index 4b465f2b0d80..f61ddf4ad787 100644 --- a/packages/CarSystemUI/res/values-uk/strings.xml +++ b/packages/CarSystemUI/res/values-uk/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Мін."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Макс."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Голос розпізнається через підключений пристрій Bluetooth"</string> + <string name="car_guest" msgid="318393171202663722">"Гість"</string> + <string name="start_guest_session" msgid="497784785761754874">"Гість"</string> + <string name="car_add_user" msgid="4067337059622483269">"Додати користувача"</string> + <string name="car_new_user" msgid="6637442369728092473">"Новий користувач"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Коли ви додаєте нового користувача, він має налаштувати свій профіль."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Усі користувачі можуть оновлювати додатки для решти людей."</string> </resources> diff --git a/packages/CarSystemUI/res/values-ur/strings.xml b/packages/CarSystemUI/res/values-ur/strings.xml new file mode 100644 index 000000000000..50342a337690 --- /dev/null +++ b/packages/CarSystemUI/res/values-ur/strings.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="hvac_min_text" msgid="8167124789068494624">"کم از کم"</string> + <string name="hvac_max_text" msgid="3669693372074755551">"زیادہ سے زیادہ"</string> + <string name="voice_recognition_toast" msgid="1149934534584052842">"آواز کی شناخت اب منسلک کردہ بلوٹوتھ آلے سے ہوتی ہے"</string> + <!-- no translation found for car_guest (318393171202663722) --> + <skip /> + <!-- no translation found for start_guest_session (497784785761754874) --> + <skip /> + <!-- no translation found for car_add_user (4067337059622483269) --> + <skip /> + <!-- no translation found for car_new_user (6637442369728092473) --> + <skip /> + <!-- no translation found for user_add_user_message_setup (1035578846007352323) --> + <skip /> + <!-- no translation found for user_add_user_message_update (7061671307004867811) --> + <skip /> +</resources> diff --git a/packages/CarSystemUI/res/values-uz/strings.xml b/packages/CarSystemUI/res/values-uz/strings.xml index 796c6498d2b1..e0f8378879d6 100644 --- a/packages/CarSystemUI/res/values-uz/strings.xml +++ b/packages/CarSystemUI/res/values-uz/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Daq."</string> <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Endi ovozni tanish Bluetooth qurilma ulanganda amalga oshadi"</string> + <string name="car_guest" msgid="318393171202663722">"Mehmon"</string> + <string name="start_guest_session" msgid="497784785761754874">"Mehmon"</string> + <string name="car_add_user" msgid="4067337059622483269">"Foydalanuvchi kiritish"</string> + <string name="car_new_user" msgid="6637442369728092473">"Yangi foydalanuvchi"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Yangi profil kiritilgach, uni sozlash lozim."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Qurilmaning istalgan foydalanuvchisi ilovalarni barcha hisoblar uchun yangilashi mumkin."</string> </resources> diff --git a/packages/CarSystemUI/res/values-vi/strings.xml b/packages/CarSystemUI/res/values-vi/strings.xml index e4f24550ffd7..ce1826bc5ee3 100644 --- a/packages/CarSystemUI/res/values-vi/strings.xml +++ b/packages/CarSystemUI/res/values-vi/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Tối thiểu"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Tối đa"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Thiết bị Bluetooth được kết nối đang xử lý vấn đề nhận dạng giọng nói"</string> + <string name="car_guest" msgid="318393171202663722">"Khách"</string> + <string name="start_guest_session" msgid="497784785761754874">"Khách"</string> + <string name="car_add_user" msgid="4067337059622483269">"Thêm người dùng"</string> + <string name="car_new_user" msgid="6637442369728092473">"Người dùng mới"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Khi bạn thêm một người dùng mới, người đó cần thiết lập không gian của mình."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Bất kỳ người dùng nào cũng có thể cập nhật ứng dụng cho tất cả những người dùng khác."</string> </resources> diff --git a/packages/CarSystemUI/res/values-zh-rCN/strings.xml b/packages/CarSystemUI/res/values-zh-rCN/strings.xml index 4f2f9ca73cdf..431fd62ea9d2 100644 --- a/packages/CarSystemUI/res/values-zh-rCN/strings.xml +++ b/packages/CarSystemUI/res/values-zh-rCN/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"最小"</string> <string name="hvac_max_text" msgid="3669693372074755551">"最大"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"现在由已连接的蓝牙设备处理语音识别操作"</string> + <string name="car_guest" msgid="318393171202663722">"访客"</string> + <string name="start_guest_session" msgid="497784785761754874">"访客"</string> + <string name="car_add_user" msgid="4067337059622483269">"添加用户"</string> + <string name="car_new_user" msgid="6637442369728092473">"新用户"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"当您添加新用户时,该用户需要自行设置个人空间。"</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"任何用户均可为所有其他用户更新应用。"</string> </resources> diff --git a/packages/CarSystemUI/res/values-zh-rHK/strings.xml b/packages/CarSystemUI/res/values-zh-rHK/strings.xml index 4ba404d6a20c..24efc22e67d8 100644 --- a/packages/CarSystemUI/res/values-zh-rHK/strings.xml +++ b/packages/CarSystemUI/res/values-zh-rHK/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"最小"</string> <string name="hvac_max_text" msgid="3669693372074755551">"最大"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"現在由已連線的藍牙裝置處理語音辨識作業"</string> + <string name="car_guest" msgid="318393171202663722">"訪客"</string> + <string name="start_guest_session" msgid="497784785761754874">"訪客"</string> + <string name="car_add_user" msgid="4067337059622483269">"新增使用者"</string> + <string name="car_new_user" msgid="6637442369728092473">"新使用者"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"新增的使用者需要自行設定個人空間。"</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"任何使用者都可以為所有其他使用者更新應用程式。"</string> </resources> diff --git a/packages/CarSystemUI/res/values-zh-rTW/strings.xml b/packages/CarSystemUI/res/values-zh-rTW/strings.xml index 4ba404d6a20c..e1356cafde26 100644 --- a/packages/CarSystemUI/res/values-zh-rTW/strings.xml +++ b/packages/CarSystemUI/res/values-zh-rTW/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"最小"</string> <string name="hvac_max_text" msgid="3669693372074755551">"最大"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"現在由已連線的藍牙裝置處理語音辨識作業"</string> + <string name="car_guest" msgid="318393171202663722">"訪客"</string> + <string name="start_guest_session" msgid="497784785761754874">"訪客"</string> + <string name="car_add_user" msgid="4067337059622483269">"新增使用者"</string> + <string name="car_new_user" msgid="6637442369728092473">"新使用者"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"新使用者必須自行設定個人空間。"</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"任何使用者都能為所有其他使用者更新應用程式。"</string> </resources> diff --git a/packages/CarSystemUI/res/values-zu/strings.xml b/packages/CarSystemUI/res/values-zu/strings.xml index 432328b60bb8..94381b70002c 100644 --- a/packages/CarSystemUI/res/values-zu/strings.xml +++ b/packages/CarSystemUI/res/values-zu/strings.xml @@ -20,4 +20,10 @@ <string name="hvac_min_text" msgid="8167124789068494624">"Okuncane"</string> <string name="hvac_max_text" msgid="3669693372074755551">"Okuningi"</string> <string name="voice_recognition_toast" msgid="1149934534584052842">"Ukubonwa kwezwi manje kuphethwe idivayisi exhunyiwe ye-Bluetooth"</string> + <string name="car_guest" msgid="318393171202663722">"Isihambeli"</string> + <string name="start_guest_session" msgid="497784785761754874">"Isihambeli"</string> + <string name="car_add_user" msgid="4067337059622483269">"Engeza umsebenzisi"</string> + <string name="car_new_user" msgid="6637442369728092473">"Umsebenzisi omusha"</string> + <string name="user_add_user_message_setup" msgid="1035578846007352323">"Uma ungeza umsebenzisi omusha, loyo muntu udinga ukusetha izikhala zakhe."</string> + <string name="user_add_user_message_update" msgid="7061671307004867811">"Noma yimuphi umsebenzisi angabuyekeza izinhlelo zokusebenza zabanye abasebenzisi."</string> </resources> diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml index a5445c56112e..eb1d9d0dd602 100644 --- a/packages/CarSystemUI/res/values/config.xml +++ b/packages/CarSystemUI/res/values/config.xml @@ -87,7 +87,7 @@ <item>com.android.systemui.util.NotificationChannels</item> <item>com.android.systemui.keyguard.KeyguardViewMediator</item> <!-- <item>com.android.systemui.recents.Recents</item>--> - <item>com.android.systemui.volume.VolumeUI</item> +<!-- <item>com.android.systemui.volume.VolumeUI</item>--> <!-- <item>com.android.systemui.stackdivider.Divider</item>--> <!-- <item>com.android.systemui.statusbar.phone.StatusBar</item>--> <item>com.android.systemui.usb.StorageNotification</item> @@ -106,9 +106,10 @@ <item>com.android.systemui.SizeCompatModeActivityController</item> <!-- <item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>--> <item>com.android.systemui.theme.ThemeOverlayController</item> - <item>com.android.systemui.navigationbar.car.CarNavigationBar</item> <item>com.android.systemui.toast.ToastUI</item> - <item>com.android.systemui.voicerecognition.car.ConnectedDeviceVoiceRecognitionNotifier</item> - <item>com.android.systemui.window.SystemUIOverlayWindowManager</item> + <item>com.android.systemui.car.navigationbar.CarNavigationBar</item> + <item>com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier</item> + <item>com.android.systemui.car.window.SystemUIOverlayWindowManager</item> + <item>com.android.systemui.car.volume.VolumeUI</item> </string-array> </resources> diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java index 59fa9d09c9ee..58e4b9a81190 100644 --- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java +++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java @@ -18,19 +18,23 @@ package com.android.systemui; import com.android.systemui.biometrics.AuthController; import com.android.systemui.bubbles.dagger.BubbleModule; +import com.android.systemui.car.navigationbar.CarNavigationBar; import com.android.systemui.car.notification.CarNotificationModule; +import com.android.systemui.car.statusbar.CarStatusBar; +import com.android.systemui.car.statusbar.CarStatusBarModule; +import com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier; +import com.android.systemui.car.volume.VolumeUI; +import com.android.systemui.car.window.OverlayWindowModule; +import com.android.systemui.car.window.SystemUIOverlayWindowManager; import com.android.systemui.globalactions.GlobalActionsComponent; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.dagger.KeyguardModule; -import com.android.systemui.navigationbar.car.CarNavigationBar; import com.android.systemui.pip.PipUI; import com.android.systemui.power.PowerUI; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsModule; import com.android.systemui.shortcut.ShortcutKeyDispatcher; import com.android.systemui.stackdivider.Divider; -import com.android.systemui.statusbar.car.CarStatusBar; -import com.android.systemui.statusbar.car.CarStatusBarModule; import com.android.systemui.statusbar.notification.InstantAppNotifier; import com.android.systemui.statusbar.notification.dagger.NotificationsModule; import com.android.systemui.statusbar.phone.StatusBar; @@ -38,10 +42,6 @@ import com.android.systemui.statusbar.tv.TvStatusBar; import com.android.systemui.theme.ThemeOverlayController; import com.android.systemui.toast.ToastUI; import com.android.systemui.util.leak.GarbageMonitor; -import com.android.systemui.voicerecognition.car.ConnectedDeviceVoiceRecognitionNotifier; -import com.android.systemui.volume.VolumeUI; -import com.android.systemui.window.OverlayWindowModule; -import com.android.systemui.window.SystemUIOverlayWindowManager; import dagger.Binds; import dagger.Module; @@ -65,7 +65,7 @@ public abstract class CarSystemUIBinder { @ClassKey(Divider.class) public abstract SystemUI bindDivider(Divider sysui); - /** */ + /** Inject Car Navigation Bar. */ @Binds @IntoMap @ClassKey(CarNavigationBar.class) diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java index 4ea48ba24fa9..f066bf589b64 100644 --- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java +++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java @@ -25,6 +25,9 @@ import com.android.keyguard.KeyguardViewController; import com.android.systemui.car.CarDeviceProvisionedController; import com.android.systemui.car.CarDeviceProvisionedControllerImpl; import com.android.systemui.car.keyguard.CarKeyguardViewController; +import com.android.systemui.car.statusbar.CarStatusBar; +import com.android.systemui.car.statusbar.CarStatusBarKeyguardViewManager; +import com.android.systemui.car.volume.CarVolumeDialogComponent; import com.android.systemui.dagger.SystemUIRootComponent; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManagerImpl; @@ -39,8 +42,6 @@ import com.android.systemui.stackdivider.DividerModule; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; -import com.android.systemui.statusbar.car.CarStatusBar; -import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; @@ -55,7 +56,6 @@ import com.android.systemui.statusbar.policy.BatteryControllerImpl; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.HeadsUpManager; -import com.android.systemui.volume.CarVolumeDialogComponent; import com.android.systemui.volume.VolumeDialogComponent; import javax.inject.Named; @@ -87,9 +87,6 @@ public abstract class CarSystemUIModule { groupManager, configurationController); } - @Binds - abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone); - @Singleton @Provides @Named(LEAK_REPORT_EMAIL_NAME) @@ -97,6 +94,16 @@ public abstract class CarSystemUIModule { return "buganizer-system+181579@google.com"; } + @Provides + @Singleton + static Recents provideRecents(Context context, RecentsImplementation recentsImplementation, + CommandQueue commandQueue) { + return new Recents(context, recentsImplementation, commandQueue); + } + + @Binds + abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone); + @Binds abstract EnhancedEstimates bindEnhancedEstimates(EnhancedEstimatesImpl enhancedEstimates); @@ -123,13 +130,6 @@ public abstract class CarSystemUIModule { @Binds abstract ShadeController provideShadeController(ShadeControllerImpl shadeController); - @Provides - @Singleton - static Recents provideRecents(Context context, RecentsImplementation recentsImplementation, - CommandQueue commandQueue) { - return new Recents(context, recentsImplementation, commandQueue); - } - @Binds abstract SystemUIRootComponent bindSystemUIRootComponent( CarSystemUIRootComponent systemUIRootComponent); diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java b/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/CarBatteryController.java index 4e0fd4ab459d..9b5e2712a527 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/CarBatteryController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.car; +package com.android.systemui.car.bluetooth; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -116,10 +116,12 @@ public class CarBatteryController extends BroadcastReceiver implements BatteryCo mChangeCallbacks.remove(cb); } + /** Sets {@link BatteryViewHandler}. */ public void addBatteryViewHandler(BatteryViewHandler batteryViewHandler) { mBatteryViewHandler = batteryViewHandler; } + /** Starts listening for bluetooth broadcast messages. */ public void startListening() { IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED); @@ -127,6 +129,7 @@ public class CarBatteryController extends BroadcastReceiver implements BatteryCo mContext.registerReceiver(this, filter); } + /** Stops listening for bluetooth broadcast messages. */ public void stopListening() { mContext.unregisterReceiver(this); } @@ -279,8 +282,10 @@ public class CarBatteryController extends BroadcastReceiver implements BatteryCo * in the {@link CarBatteryController}. */ public interface BatteryViewHandler { + /** Hides the battery view. */ void hideBatteryView(); + /** Shows the battery view. */ void showBatteryView(); } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java b/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/ConnectedDeviceSignalController.java index 3288927bf730..4642868a225e 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/ConnectedDeviceSignalController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.car; +package com.android.systemui.car.bluetooth; import static com.android.systemui.statusbar.phone.StatusBar.DEBUG; @@ -125,6 +125,7 @@ public class ConnectedDeviceSignalController extends BroadcastReceiver implement BluetoothProfile.HEADSET_CLIENT); } + /** Starts listening for bluetooth broadcast messages. */ public void startListening() { IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED); @@ -134,6 +135,7 @@ public class ConnectedDeviceSignalController extends BroadcastReceiver implement mController.addCallback(this); } + /** Stops listening for bluetooth broadcast messages. */ public void stopListening() { mContext.unregisterReceiver(this); mController.removeCallback(this); diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/AnimatedTemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java index 908aaad71893..a7294317f46c 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/AnimatedTemperatureView.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,10 +11,10 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License + * limitations under the License. */ -package com.android.systemui.statusbar.hvac; +package com.android.systemui.car.hvac; import android.animation.ObjectAnimator; import android.annotation.SuppressLint; @@ -35,7 +35,6 @@ import android.widget.TextSwitcher; import android.widget.TextView; import com.android.systemui.R; -import com.android.systemui.navigationbar.car.hvac.TemperatureView; /** * Simple text display of HVAC properties, It is designed to show mTemperature and is configured in diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/hvac/HvacController.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java index fd9c488278ba..af8ddb6a8180 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/hvac/HvacController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car.hvac; +package com.android.systemui.car.hvac; import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL; import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS; diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureBackgroundAnimator.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureBackgroundAnimator.java index 3c6d623c8ff7..a4c45730a9c2 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureBackgroundAnimator.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureBackgroundAnimator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,15 +11,15 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License + * limitations under the License. */ -package com.android.systemui.statusbar.hvac; +package com.android.systemui.car.hvac; -import static com.android.systemui.statusbar.hvac.AnimatedTemperatureView.isHorizontal; -import static com.android.systemui.statusbar.hvac.AnimatedTemperatureView.isLeft; -import static com.android.systemui.statusbar.hvac.AnimatedTemperatureView.isTop; -import static com.android.systemui.statusbar.hvac.AnimatedTemperatureView.isVertical; +import static com.android.systemui.car.hvac.AnimatedTemperatureView.isHorizontal; +import static com.android.systemui.car.hvac.AnimatedTemperatureView.isLeft; +import static com.android.systemui.car.hvac.AnimatedTemperatureView.isTop; +import static com.android.systemui.car.hvac.AnimatedTemperatureView.isVertical; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureColorStore.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureColorStore.java index a40ffaf850c5..9a7b0b9819c5 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureColorStore.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureColorStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,10 +11,10 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License + * limitations under the License. */ -package com.android.systemui.statusbar.hvac; +package com.android.systemui.car.hvac; import android.graphics.Color; diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureTextAnimator.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextAnimator.java index 8ee5ef6badc3..74d970464108 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureTextAnimator.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextAnimator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License + * limitations under the License. */ -package com.android.systemui.statusbar.hvac; +package com.android.systemui.car.hvac; -import static com.android.systemui.statusbar.hvac.AnimatedTemperatureView.isHorizontal; -import static com.android.systemui.statusbar.hvac.AnimatedTemperatureView.isLeft; +import static com.android.systemui.car.hvac.AnimatedTemperatureView.isHorizontal; +import static com.android.systemui.car.hvac.AnimatedTemperatureView.isLeft; import android.annotation.NonNull; import android.view.animation.AccelerateDecelerateInterpolator; diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/hvac/TemperatureTextView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java index ad4fcd9b67da..521a665da5f6 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/hvac/TemperatureTextView.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car.hvac; +package com.android.systemui.car.hvac; import android.content.Context; import android.content.res.TypedArray; diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/hvac/TemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java index 963f3184c40d..6b903fad505c 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/hvac/TemperatureView.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car.hvac; +package com.android.systemui.car.hvac; /** * Interface for Views that display temperature HVAC properties diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java index 4fde30987e50..b5f648b7ef3b 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java @@ -35,9 +35,11 @@ import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.R; import com.android.systemui.SystemUIFactory; import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.car.navigationbar.CarNavigationBarController; +import com.android.systemui.car.window.OverlayViewController; +import com.android.systemui.car.window.OverlayViewGlobalStateController; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.keyguard.DismissCallbackRegistry; -import com.android.systemui.navigationbar.car.CarNavigationBarController; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.KeyguardBouncer; @@ -45,8 +47,6 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.window.OverlayViewController; -import com.android.systemui.window.OverlayViewGlobalStateController; import javax.inject.Inject; import javax.inject.Singleton; diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewMediator.java index db0f5d82e210..5a35c482fb36 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewMediator.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewMediator.java @@ -17,7 +17,7 @@ package com.android.systemui.car.keyguard; import com.android.systemui.car.userswitcher.FullScreenUserSwitcherViewController; -import com.android.systemui.window.OverlayViewMediator; +import com.android.systemui.car.window.OverlayViewMediator; import javax.inject.Inject; import javax.inject.Singleton; diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/AssitantButton.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/AssitantButton.java index 98cc00e376cc..69ec78eab593 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/AssitantButton.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/AssitantButton.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE; diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java index c36aaa092b06..eedcfa548e5a 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import android.app.ActivityManager; import android.content.ComponentName; diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateListener.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java index 9da412111f07..13617983b23b 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateListener.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import android.app.ActivityTaskManager; import android.util.Log; diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java index 2c2aec21ea4f..2b5cab783916 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; @@ -51,7 +51,6 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.statusbar.AutoHideUiElement; import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.BarTransitions; import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy; @@ -78,7 +77,6 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks private final ButtonSelectionStateListener mButtonSelectionStateListener; private final Handler mMainHandler; private final Lazy<KeyguardStateController> mKeyguardStateControllerLazy; - private final Lazy<NavigationBarController> mNavigationBarControllerLazy; private final ButtonSelectionStateController mButtonSelectionStateController; private final PhoneStatusBarPolicy mIconPolicy; private final StatusBarIconController mIconController; @@ -124,7 +122,6 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks ButtonSelectionStateListener buttonSelectionStateListener, @Main Handler mainHandler, Lazy<KeyguardStateController> keyguardStateControllerLazy, - Lazy<NavigationBarController> navigationBarControllerLazy, ButtonSelectionStateController buttonSelectionStateController, PhoneStatusBarPolicy iconPolicy, StatusBarIconController iconController @@ -139,7 +136,6 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks mButtonSelectionStateListener = buttonSelectionStateListener; mMainHandler = mainHandler; mKeyguardStateControllerLazy = keyguardStateControllerLazy; - mNavigationBarControllerLazy = navigationBarControllerLazy; mButtonSelectionStateController = buttonSelectionStateController; mIconPolicy = iconPolicy; mIconController = iconController; @@ -315,11 +311,6 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks result.mImeWindowVis, result.mImeBackDisposition, result.mShowImeSwitcher); } - - // There has been a car customized nav bar on the default display, so just create nav bars - // on external displays. - mNavigationBarControllerLazy.get().createNavigationBars(/* includeDefaultDisplay= */ false, - result); } private void buildNavBarWindows() { diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java index 37a82255929a..55c11530fc37 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import android.content.Context; import android.view.View; @@ -24,7 +24,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.systemui.R; -import com.android.systemui.navigationbar.car.hvac.HvacController; +import com.android.systemui.car.hvac.HvacController; import javax.inject.Inject; import javax.inject.Singleton; diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java index 5b99f53af9f9..46a720b88419 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import android.content.Context; import android.util.AttributeSet; @@ -24,7 +24,7 @@ import android.widget.LinearLayout; import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.navigationbar.car.CarNavigationBarController.NotificationsShadeController; +import com.android.systemui.car.navigationbar.CarNavigationBarController.NotificationsShadeController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.StatusBarIconController; diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationButton.java index b4d478572daf..5f4ac2dcb141 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationButton.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import android.app.ActivityOptions; import android.content.Context; diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/NavigationBarViewFactory.java index e47c5d1307ac..3b7b48a77186 100644 --- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/NavigationBarViewFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import android.content.Context; import android.util.ArrayMap; diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java index d8a894cfa8ba..a17a0e9d2920 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java @@ -45,13 +45,13 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.R; import com.android.systemui.car.CarDeviceProvisionedController; import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.car.window.OverlayPanelViewController; +import com.android.systemui.car.window.OverlayViewGlobalStateController; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.window.OverlayPanelViewController; -import com.android.systemui.window.OverlayViewGlobalStateController; import javax.inject.Inject; import javax.inject.Singleton; diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java index 9d71797794b8..24a84d940577 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java @@ -20,10 +20,9 @@ import android.car.hardware.power.CarPowerManager; import android.content.res.Configuration; import com.android.systemui.car.CarDeviceProvisionedController; -import com.android.systemui.navigationbar.car.CarNavigationBarController; -import com.android.systemui.statusbar.car.PowerManagerHelper; +import com.android.systemui.car.navigationbar.CarNavigationBarController; +import com.android.systemui.car.window.OverlayViewMediator; import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.window.OverlayViewMediator; import javax.inject.Inject; import javax.inject.Singleton; diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/PowerManagerHelper.java index 615a7bae2930..92a11d8db88f 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/PowerManagerHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.car; +package com.android.systemui.car.notification; import android.annotation.NonNull; import android.car.Car; diff --git a/packages/CarSystemUI/src/com/android/systemui/sideloaded/car/CarSideLoadedAppDetector.java b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/CarSideLoadedAppDetector.java index c0dbb5879d7d..f145b148eaf7 100644 --- a/packages/CarSystemUI/src/com/android/systemui/sideloaded/car/CarSideLoadedAppDetector.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/CarSideLoadedAppDetector.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.sideloaded.car; +package com.android.systemui.car.sideloaded; import android.annotation.NonNull; import android.app.ActivityManager; diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBar.java index ec1dabc1bd72..b6eb015008af 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBar.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.car; +package com.android.systemui.car.statusbar; import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME; @@ -41,6 +41,8 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.car.CarDeviceProvisionedController; import com.android.systemui.car.CarDeviceProvisionedListener; +import com.android.systemui.car.bluetooth.CarBatteryController; +import com.android.systemui.car.navigationbar.CarNavigationBarController; import com.android.systemui.classifier.FalsingLog; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.UiBackground; @@ -49,7 +51,6 @@ import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; -import com.android.systemui.navigationbar.car.CarNavigationBarController; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.PluginDependencyProvider; diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarKeyguardViewManager.java index e1c051f5012d..96a998a500e1 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarKeyguardViewManager.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.car; +package com.android.systemui.car.statusbar; import android.content.Context; import android.view.View; @@ -23,8 +23,8 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.R; +import com.android.systemui.car.navigationbar.CarNavigationBarController; import com.android.systemui.dock.DockManager; -import com.android.systemui.navigationbar.car.CarNavigationBarController; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.phone.NavigationModeController; diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarModule.java index f72ab25a8028..dc2eb04c2990 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarModule.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.car; +package com.android.systemui.car.statusbar; import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME; @@ -31,13 +31,13 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.car.CarDeviceProvisionedController; +import com.android.systemui.car.navigationbar.CarNavigationBarController; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; -import com.android.systemui.navigationbar.car.CarNavigationBarController; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.PluginDependencyProvider; diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java index 45ceb6d1551f..10b2b973071a 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java @@ -25,9 +25,9 @@ import android.view.View; import androidx.recyclerview.widget.GridLayoutManager; import com.android.systemui.R; +import com.android.systemui.car.window.OverlayViewController; +import com.android.systemui.car.window.OverlayViewGlobalStateController; import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.window.OverlayViewController; -import com.android.systemui.window.OverlayViewGlobalStateController; import javax.inject.Inject; import javax.inject.Singleton; diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java index 149531f75029..346c38ced766 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java @@ -17,9 +17,9 @@ package com.android.systemui.car.userswitcher; import com.android.systemui.car.keyguard.CarKeyguardViewController; +import com.android.systemui.car.window.OverlayViewMediator; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.window.OverlayViewMediator; import javax.inject.Inject; import javax.inject.Singleton; diff --git a/packages/CarSystemUI/src/com/android/systemui/voicerecognition/car/ConnectedDeviceVoiceRecognitionNotifier.java b/packages/CarSystemUI/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifier.java index 2f79f960f951..c054d204af98 100644 --- a/packages/CarSystemUI/src/com/android/systemui/voicerecognition/car/ConnectedDeviceVoiceRecognitionNotifier.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifier.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.voicerecognition.car; +package com.android.systemui.car.voicerecognition; import android.bluetooth.BluetoothHeadsetClient; import android.content.BroadcastReceiver; diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java index 5a3443674cf4..98d24b1fc0e4 100644 --- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,13 +14,15 @@ * limitations under the License. */ -package com.android.systemui.volume; +package com.android.systemui.car.volume; import android.content.Context; import com.android.systemui.car.CarServiceProvider; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.plugins.VolumeDialog; +import com.android.systemui.volume.VolumeDialogComponent; +import com.android.systemui.volume.VolumeDialogControllerImpl; import javax.inject.Inject; import javax.inject.Singleton; diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java index 873d7d7975e0..12818840af9a 100644 --- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.volume; +package com.android.systemui.car.volume; import android.animation.Animator; import android.animation.AnimatorInflater; @@ -61,6 +61,9 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.systemui.R; import com.android.systemui.car.CarServiceProvider; import com.android.systemui.plugins.VolumeDialog; +import com.android.systemui.volume.Events; +import com.android.systemui.volume.SystemUIInterpolators; +import com.android.systemui.volume.VolumeDialogImpl; import org.xmlpull.v1.XmlPullParserException; @@ -75,7 +78,8 @@ import java.util.List; */ public class CarVolumeDialogImpl implements VolumeDialog { - private static final String TAG = Util.logTag(CarVolumeDialogImpl.class); + private static final String TAG = "CarVolumeDialog"; + private static final boolean DEBUG = false; private static final String XML_TAG_VOLUME_ITEMS = "carVolumeItems"; private static final String XML_TAG_VOLUME_ITEM = "item"; @@ -134,9 +138,9 @@ public class CarVolumeDialogImpl implements VolumeDialog { // this // callback. Updating the seekbar at the same time could block the continuous // seeking. - if (value != volumeItem.progress && isShowing) { - volumeItem.carVolumeItem.setProgress(value); - volumeItem.progress = value; + if (value != volumeItem.mProgress && isShowing) { + volumeItem.mCarVolumeItem.setProgress(value); + volumeItem.mProgress = value; } if ((flags & AudioManager.FLAG_SHOW_UI) != 0) { mPreviouslyDisplayingGroupId = mCurrentlyDisplayingGroupId; @@ -234,6 +238,20 @@ public class CarVolumeDialogImpl implements VolumeDialog { cleanupAudioManager(); } + /** + * Reveals volume dialog. + */ + public void show(int reason) { + mHandler.obtainMessage(H.SHOW, reason).sendToTarget(); + } + + /** + * Hides volume dialog. + */ + public void dismiss(int reason) { + mHandler.obtainMessage(H.DISMISS, reason).sendToTarget(); + } + private void initDialog() { loadAudioUsageItems(); mCarVolumeLineItems.clear(); @@ -293,7 +311,7 @@ public class CarVolumeDialogImpl implements VolumeDialog { private void showH(int reason) { - if (D.BUG) { + if (DEBUG) { Log.d(TAG, "showH r=" + Events.DISMISS_REASONS[reason]); } @@ -323,7 +341,7 @@ public class CarVolumeDialogImpl implements VolumeDialog { private void clearAllAndSetupDefaultCarVolumeLineItem(int groupId) { mCarVolumeLineItems.clear(); VolumeItem volumeItem = mAvailableVolumeItems.get(groupId); - volumeItem.defaultItem = true; + volumeItem.mDefaultItem = true; addCarVolumeListItem(volumeItem, /* volumeGroupId = */ groupId, R.drawable.car_ic_keyboard_arrow_down, new ExpandIconListener()); } @@ -334,7 +352,7 @@ public class CarVolumeDialogImpl implements VolumeDialog { mHandler.sendMessageDelayed(mHandler .obtainMessage(H.DISMISS, Events.DISMISS_REASON_TIMEOUT), timeout); - if (D.BUG) { + if (DEBUG) { Log.d(TAG, "rescheduleTimeout " + timeout + " " + Debug.getCaller()); } } @@ -348,7 +366,7 @@ public class CarVolumeDialogImpl implements VolumeDialog { } private void dismissH(int reason) { - if (D.BUG) { + if (DEBUG) { Log.d(TAG, "dismissH r=" + Events.DISMISS_REASONS[reason]); } @@ -365,7 +383,7 @@ public class CarVolumeDialogImpl implements VolumeDialog { .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS) .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator()) .withEndAction(() -> mHandler.postDelayed(() -> { - if (D.BUG) { + if (DEBUG) { Log.d(TAG, "mDialog.dismiss()"); } mDialog.dismiss(); @@ -410,8 +428,8 @@ public class CarVolumeDialogImpl implements VolumeDialog { /* defValue= */ -1); if (usage >= 0) { VolumeItem volumeItem = new VolumeItem(); - volumeItem.rank = rank; - volumeItem.icon = item.getResourceId( + volumeItem.mRank = rank; + volumeItem.mIcon = item.getResourceId( R.styleable.carVolumeItems_item_icon, /* defValue= */ 0); mVolumeItems.put(usage, volumeItem); rank++; @@ -429,8 +447,8 @@ public class CarVolumeDialogImpl implements VolumeDialog { VolumeItem result = null; for (int usage : usages) { VolumeItem volumeItem = mVolumeItems.get(usage); - if (volumeItem.rank < rank) { - rank = volumeItem.rank; + if (volumeItem.mRank < rank) { + rank = volumeItem.mRank; result = volumeItem; } } @@ -449,7 +467,7 @@ public class CarVolumeDialogImpl implements VolumeDialog { carVolumeItem.setGroupId(volumeGroupId); int color = mContext.getColor(R.color.car_volume_dialog_tint); - Drawable primaryIcon = mContext.getDrawable(volumeItem.icon); + Drawable primaryIcon = mContext.getDrawable(volumeItem.mIcon); primaryIcon.mutate().setTint(color); carVolumeItem.setPrimaryIcon(primaryIcon); if (supplementalIcon != null) { @@ -462,8 +480,8 @@ public class CarVolumeDialogImpl implements VolumeDialog { /* showSupplementalIconDivider= */ false); } - volumeItem.carVolumeItem = carVolumeItem; - volumeItem.progress = seekbarProgressValue; + volumeItem.mCarVolumeItem = carVolumeItem; + volumeItem.mProgress = seekbarProgressValue; return carVolumeItem; } @@ -490,13 +508,12 @@ public class CarVolumeDialogImpl implements VolumeDialog { * Wrapper class which contains information of each volume group. */ private static class VolumeItem { - - private int rank; - private boolean defaultItem = false; + private int mRank; + private boolean mDefaultItem = false; @DrawableRes - private int icon; - private CarVolumeItem carVolumeItem; - private int progress; + private int mIcon; + private CarVolumeItem mCarVolumeItem; + private int mProgress; } private final class H extends Handler { @@ -624,9 +641,9 @@ public class CarVolumeDialogImpl implements VolumeDialog { Log.w(TAG, "Ignoring volume change event because the car isn't connected"); return; } - mAvailableVolumeItems.get(mVolumeGroupId).progress = progress; + mAvailableVolumeItems.get(mVolumeGroupId).mProgress = progress; mAvailableVolumeItems.get( - mVolumeGroupId).carVolumeItem.setProgress(progress); + mVolumeGroupId).mCarVolumeItem.setProgress(progress); mCarAudioManager.setGroupVolume(mVolumeGroupId, progress, 0); } diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItem.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItem.java index b83740f4259d..1e7e5348b7fa 100644 --- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItem.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItem.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.volume; +package com.android.systemui.car.volume; import android.graphics.drawable.Drawable; import android.view.View; @@ -38,12 +38,12 @@ public class CarVolumeItem { private int mMax; private int mProgress; private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener; - + /** * Called when {@link CarVolumeItem} is bound to its ViewHolder. */ void bind(CarVolumeItemViewHolder viewHolder) { - viewHolder.bind(/* carVolumeItem= */ this); + viewHolder.bind(/* carVolumeItem= */ this); } /** Sets progress of seekbar. */ diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItemAdapter.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItemAdapter.java index 5c1f8170afc4..7f336b5250a7 100644 --- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItemAdapter.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItemAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.volume; +package com.android.systemui.car.volume; import android.content.Context; import android.view.LayoutInflater; diff --git a/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java new file mode 100644 index 000000000000..2bdb85ff9acc --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.car.volume; + +import android.car.Car; +import android.car.media.CarAudioManager; +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.os.Handler; +import android.util.Log; + +import com.android.systemui.R; +import com.android.systemui.SystemUI; +import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.volume.VolumeDialogComponent; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import dagger.Lazy; + +/** The entry point for controlling the volume ui in cars. */ +@Singleton +public class VolumeUI extends SystemUI { + + private static final String TAG = "VolumeUI"; + private final Resources mResources; + private final Handler mMainHandler; + private final CarServiceProvider mCarServiceProvider; + private final Lazy<VolumeDialogComponent> mVolumeDialogComponentLazy; + + private final CarAudioManager.CarVolumeCallback mVolumeChangeCallback = + new CarAudioManager.CarVolumeCallback() { + @Override + public void onGroupVolumeChanged(int zoneId, int groupId, int flags) { + if (mVolumeDialogComponent == null) { + mMainHandler.post(() -> { + mVolumeDialogComponent = mVolumeDialogComponentLazy.get(); + mVolumeDialogComponent.register(); + }); + mCarAudioManager.unregisterCarVolumeCallback(mVolumeChangeCallback); + } + } + + @Override + public void onMasterMuteChanged(int zoneId, int flags) { + // ignored + } + }; + + private boolean mEnabled; + private CarAudioManager mCarAudioManager; + private VolumeDialogComponent mVolumeDialogComponent; + + @Inject + public VolumeUI( + Context context, + @Main Resources resources, + @Main Handler mainHandler, + CarServiceProvider carServiceProvider, + Lazy<VolumeDialogComponent> volumeDialogComponentLazy + ) { + super(context); + mResources = resources; + mMainHandler = mainHandler; + mCarServiceProvider = carServiceProvider; + mVolumeDialogComponentLazy = volumeDialogComponentLazy; + } + + @Override + public void start() { + boolean enableVolumeUi = mResources.getBoolean(R.bool.enable_volume_ui); + mEnabled = enableVolumeUi; + if (!mEnabled) return; + + mCarServiceProvider.addListener(car -> { + if (mCarAudioManager != null) { + return; + } + + mCarAudioManager = (CarAudioManager) car.getCarManager(Car.AUDIO_SERVICE); + Log.d(TAG, "Registering mVolumeChangeCallback."); + // This volume call back is never unregistered because CarStatusBar is + // never destroyed. + mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback); + }); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (!mEnabled) return; + if (mVolumeDialogComponent != null) { + mVolumeDialogComponent.onConfigurationChanged(newConfig); + } + } + + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + pw.print("mEnabled="); pw.println(mEnabled); + if (!mEnabled) return; + if (mVolumeDialogComponent != null) { + mVolumeDialogComponent.dump(fd, pw, args); + } + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/window/OverlayPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java index 58022f12e58c..90892d5c53e4 100644 --- a/packages/CarSystemUI/src/com/android/systemui/window/OverlayPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.window; +package com.android.systemui.car.window; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; diff --git a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java index 15ef0be38d4d..87f20208476b 100644 --- a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.window; +package com.android.systemui.car.window; import android.view.View; import android.view.ViewGroup; diff --git a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewGlobalStateController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java index 5fe03f17919b..290505f5042a 100644 --- a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewGlobalStateController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.systemui.window; +package com.android.systemui.car.window; import android.util.Log; import androidx.annotation.VisibleForTesting; -import com.android.systemui.navigationbar.car.CarNavigationBarController; +import com.android.systemui.car.navigationbar.CarNavigationBarController; import java.util.HashSet; import java.util.Set; diff --git a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java index 7c34fb494de6..ac574eda4c9f 100644 --- a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewMediator.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.window; +package com.android.systemui.car.window; /** * Controls when to show and hide {@link OverlayViewController}(s). diff --git a/packages/CarSystemUI/src/com/android/systemui/window/OverlayWindowModule.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java index 6b4f3e37bc18..c46b287ade5a 100644 --- a/packages/CarSystemUI/src/com/android/systemui/window/OverlayWindowModule.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.window; +package com.android.systemui.car.window; import com.android.systemui.car.keyguard.CarKeyguardViewMediator; import com.android.systemui.car.notification.NotificationPanelViewMediator; diff --git a/packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java index 5df5d6e98f18..bcd96f63a2b4 100644 --- a/packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.window; +package com.android.systemui.car.window; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; diff --git a/packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowManager.java b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java index af0f17d50ee2..3f88422ba2e5 100644 --- a/packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowManager.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.window; +package com.android.systemui.car.window; import android.content.Context; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/hvac/HvacControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java index a71d1db3ee70..7996170ba7d6 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/hvac/HvacControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car.hvac; +package com.android.systemui.car.hvac; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java index d4cf6ccf4b9e..d40b1af67ca6 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java @@ -38,15 +38,15 @@ import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.car.navigationbar.CarNavigationBarController; +import com.android.systemui.car.window.OverlayViewGlobalStateController; +import com.android.systemui.car.window.SystemUIOverlayWindowController; import com.android.systemui.keyguard.DismissCallbackRegistry; -import com.android.systemui.navigationbar.car.CarNavigationBarController; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.KeyguardBouncer; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.window.OverlayViewGlobalStateController; -import com.android.systemui.window.SystemUIOverlayWindowController; import org.junit.Before; import org.junit.Test; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/ButtonSelectionStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java index f94dd82dbd98..893057e222a9 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/ButtonSelectionStateControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import static com.google.common.truth.Truth.assertThat; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java index bbcd0d4eff81..911f624d1fb3 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import static com.google.common.truth.Truth.assertThat; @@ -31,7 +31,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; -import com.android.systemui.navigationbar.car.hvac.HvacController; +import com.android.systemui.car.hvac.HvacController; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.phone.StatusBarIconController; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java index 6da34d4dddc0..6620e9d506ab 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; @@ -37,7 +37,6 @@ import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.car.CarDeviceProvisionedController; import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy; import com.android.systemui.statusbar.phone.StatusBarIconController; @@ -72,8 +71,6 @@ public class CarNavigationBarTest extends SysuiTestCase { @Mock private KeyguardStateController mKeyguardStateController; @Mock - private NavigationBarController mNavigationBarController; - @Mock private ButtonSelectionStateController mButtonSelectionStateController; @Mock private PhoneStatusBarPolicy mIconPolicy; @@ -88,8 +85,8 @@ public class CarNavigationBarTest extends SysuiTestCase { mCarNavigationBar = new CarNavigationBar(mContext, mTestableResources.getResources(), mCarNavigationBarController, mWindowManager, mDeviceProvisionedController, new CommandQueue(mContext), mAutoHideController, mButtonSelectionStateListener, - mHandler, () -> mKeyguardStateController, () -> mNavigationBarController, - mButtonSelectionStateController, mIconPolicy, mIconController); + mHandler, () -> mKeyguardStateController, mButtonSelectionStateController, + mIconPolicy, mIconController); } @Test diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarViewTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java index 9e2131c9ccfb..19e394f69af4 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarViewTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import static com.google.common.truth.Truth.assertThat; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationButtonTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java index 96d567d3a8b5..11f2fa48783f 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationButtonTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.navigationbar.car; +package com.android.systemui.car.navigationbar; import static com.google.common.truth.Truth.assertThat; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/sideloaded/car/CarSideLoadedAppDetectorTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/CarSideLoadedAppDetectorTest.java index aebb0e005019..80f3d1ee5dec 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/sideloaded/car/CarSideLoadedAppDetectorTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/CarSideLoadedAppDetectorTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.sideloaded.car; +package com.android.systemui.car.sideloaded; import static com.google.common.truth.Truth.assertThat; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/voicerecognition/car/ConnectedDeviceVoiceRecognitionNotifierTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java index 38b47d0aea5d..eca51e34995c 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/voicerecognition/car/ConnectedDeviceVoiceRecognitionNotifierTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.android.systemui.voicerecognition.car; +package com.android.systemui.car.voicerecognition; -import static com.android.systemui.voicerecognition.car.ConnectedDeviceVoiceRecognitionNotifier.INVALID_VALUE; -import static com.android.systemui.voicerecognition.car.ConnectedDeviceVoiceRecognitionNotifier.VOICE_RECOGNITION_STARTED; +import static com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier.INVALID_VALUE; +import static com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier.VOICE_RECOGNITION_STARTED; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayPanelViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java index 04f2d06ca71c..70f1d25fe2a4 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayPanelViewControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.window; +package com.android.systemui.car.window; import static com.google.common.truth.Truth.assertThat; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java index 331326168ba4..c24a3b52e348 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.window; +package com.android.systemui.car.window; import static com.google.common.truth.Truth.assertThat; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewGlobalStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java index a96b90636891..25dd4f502fb7 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewGlobalStateControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.window; +package com.android.systemui.car.window; import static com.google.common.truth.Truth.assertThat; @@ -30,7 +30,7 @@ import android.widget.FrameLayout; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; -import com.android.systemui.navigationbar.car.CarNavigationBarController; +import com.android.systemui.car.navigationbar.CarNavigationBarController; import org.junit.Before; import org.junit.Test; diff --git a/packages/CtsShim/apk/arm/CtsShim.apk b/packages/CtsShim/apk/arm/CtsShim.apk Binary files differindex 7d9f8e3fe21e..7bdb2a830d6f 100644 --- a/packages/CtsShim/apk/arm/CtsShim.apk +++ b/packages/CtsShim/apk/arm/CtsShim.apk diff --git a/packages/CtsShim/apk/arm/CtsShimPriv.apk b/packages/CtsShim/apk/arm/CtsShimPriv.apk Binary files differindex dcccada3c8a3..8efd3b248a88 100644 --- a/packages/CtsShim/apk/arm/CtsShimPriv.apk +++ b/packages/CtsShim/apk/arm/CtsShimPriv.apk diff --git a/packages/CtsShim/apk/x86/CtsShim.apk b/packages/CtsShim/apk/x86/CtsShim.apk Binary files differindex 7d9f8e3fe21e..7bdb2a830d6f 100644 --- a/packages/CtsShim/apk/x86/CtsShim.apk +++ b/packages/CtsShim/apk/x86/CtsShim.apk diff --git a/packages/CtsShim/apk/x86/CtsShimPriv.apk b/packages/CtsShim/apk/x86/CtsShimPriv.apk Binary files differindex 3501fa424123..eed29d1a729a 100644 --- a/packages/CtsShim/apk/x86/CtsShimPriv.apk +++ b/packages/CtsShim/apk/x86/CtsShimPriv.apk diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java index 617305cf6e5e..f1ec606243c4 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java @@ -433,7 +433,7 @@ public class ExternalStorageProvider extends FileSystemProvider { final int splitIndex = docId.indexOf(':', 1); final String path = docId.substring(splitIndex + 1); - File target = visible ? root.visiblePath : root.path; + File target = root.visiblePath != null ? root.visiblePath : root.path; if (target == null) { return null; } diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 90526dbea0ea..1eef0b7ccf04 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Sal waarskynlik hou tot omtrent <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Tot <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Battery kan teen <xliff:g id="TIME">%1$s</xliff:g> afloop"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Minder as <xliff:g id="THRESHOLD">%1$s</xliff:g> oor"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Minder as <xliff:g id="THRESHOLD">%1$s</xliff:g> oor (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Meer as <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Meer as <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Foon sal dalk binnekort afgaan"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet sal dalk binnekort afgaan"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Toestel sal dalk binnekort afgaan"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 96c4a65c72bc..f8dcb3a68a89 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"እስከ <xliff:g id="TIME">%1$s</xliff:g> ገደማ መቆየት አለበት"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"እስከ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ባትሪ እስከ <xliff:g id="TIME">%1$s</xliff:g> ድረስ ሊያልቅ ይችላል"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"ከ<xliff:g id="THRESHOLD">%1$s</xliff:g> ያነሰ ይቀራል"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"ከ<xliff:g id="THRESHOLD">%1$s</xliff:g> ያነሰ ይቀራል (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"ከ<xliff:g id="TIME_REMAINING">%1$s</xliff:g> በላይ ይቀራል (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"ከ<xliff:g id="TIME_REMAINING">%1$s</xliff:g> በላይ ይቀራል"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ስልኩ በቅርቡ ሊዘጋ ይችላል"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ጡባዊው በቅርቡ ሊዘጋ ይችላል"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"መሣሪያው በቅርቡ ሊዘጋ ይችላል"</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index cdbdc9a08386..aee506175875 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g>."</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"حتى <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"قد ينفد شحن البطارية قبل <xliff:g id="TIME">%1$s</xliff:g>."</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"يتبقى أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g>."</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"يتبقى أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"يتبقى أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"يتبقى أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g>."</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"قد يتم إغلاق الهاتف قريبًا"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"قد يتم إغلاق الجهاز اللوحي قريبًا"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"قد يتم إغلاق الجهاز قريبًا"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index 4ec5156023a5..40eb00b2396c 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> olana qədər davam edəcək"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> olana qədər"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batareya <xliff:g id="TIME">%1$s</xliff:g> radələrinə qədər boşala bilər"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Qalan vaxt <xliff:g id="THRESHOLD">%1$s</xliff:g> və daha azdır"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Qalan vaxt <xliff:g id="THRESHOLD">%1$s</xliff:g> və daha azdır (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Qalan vaxt <xliff:g id="TIME_REMAINING">%1$s</xliff:g> və daha çoxdur (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Qalan vaxt <xliff:g id="TIME_REMAINING">%1$s</xliff:g> və daha çoxdur"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon tezliklə sönə bilər"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Planşet tezliklə sönə bilər"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Cihaz tezliklə sönə bilər"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index a93b42297c2e..e9d314bd28f6 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Trajaće približno do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterija će se možda isprazniti do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon će se uskoro isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet će se uskoro isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Uređaj će se uskoro isključiti"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 32ed89537e80..713c7cd8065d 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Зараду хопіць прыблізна да <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Да <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Акумулятар разрадзіцца ў <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Засталося менш за <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Узровень зараду батарэі: <xliff:g id="LEVEL">%2$s</xliff:g> (хопіць менш чым на <xliff:g id="THRESHOLD">%1$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Узровень зараду батарэі: <xliff:g id="LEVEL">%2$s</xliff:g> (хопіць больш чым на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Хопіць больш чым на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Тэлефон у хуткім часе выключыцца"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшэт у хуткім часе выключыцца"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Прылада ў хуткім часе выключыцца"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 0e5ae097d47f..57456d9a7ca6 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Следва да издържи до около <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батерията може да се изтощи до <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Остава/т по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Остава/т по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Остава/т повече от <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Остава/т повече от <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Възможно е телефонът да се изключи скоро"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Възможно е таблетът да се изключи скоро"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Възможно е устройството да се изключи скоро"</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index babf00b585e2..decb3da257c1 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"আনুমানিক <xliff:g id="TIME">%1$s</xliff:g> পর্যন্ত চলবে"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> পর্যন্ত"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ব্যাটারির চার্জ <xliff:g id="TIME">%1$s</xliff:g>-এ শেষ হয়ে যেতে পারে"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> এর থেকেও কম বাকি আছে"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"আর <xliff:g id="THRESHOLD">%1$s</xliff:g>-এর কম চার্জ বাকি আছে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"আরও <xliff:g id="TIME_REMAINING">%1$s</xliff:g>-এর বেশি চলবে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"আরও <xliff:g id="TIME_REMAINING">%1$s</xliff:g>-এর বেশি চলবে"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ফোন শীঘ্রই বন্ধ হয়ে যেতে পারে"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ট্যাবলেটটি শীঘ্রই বন্ধ হয়ে যেতে পারে"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ডিভাইসটি শীঘ্রই বন্ধ হয়ে যেতে পারে"</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index 2495fd5d2fa2..0a9d260088f1 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Trebala bi trajati otprilike do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterija bi se mogla isprazniti do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Preostalo je više od: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon će se uskoro isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet će se uskoro isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Uređaj će se uskoro isključiti"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 32ff89fd6076..ffa55afd2092 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Mitjana"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Ràpida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Molt ràpida"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducat"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducada"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconnectat"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"S\'està desconnectant..."</string> @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Fins a les <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"És possible que la bateria s\'esgoti a les <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Temps restant inferior a <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Temps restant inferior a <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Temps restant superior a <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Temps restant superior a <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"És possible que el telèfon s\'apagui aviat"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"És possible que la tauleta s\'apagui aviat"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"És possible que el dispositiu s\'apagui aviat"</string> @@ -508,7 +512,7 @@ <string name="alarm_template_far" msgid="6382760514842998629">"Data: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durada"</string> <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pregunta sempre"</string> - <string name="zen_mode_forever" msgid="3339224497605461291">"Fins que no ho desactivis"</string> + <string name="zen_mode_forever" msgid="3339224497605461291">"Fins que no el desactivis"</string> <string name="time_unit_just_now" msgid="3006134267292728099">"Ara mateix"</string> <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Altaveu del telèfon"</string> <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Hi ha hagut un problema amb la connexió. Desactiva el dispositiu i torna\'l a activar."</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 26db499aa40a..504cc5eef7b5 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterie se může vybít do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Zbývá méně než <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Zbývá méně než <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Zbývá více než <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Zbývá více než <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon se brzy vypne"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet se brzy vypne"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Zařízení se brzy vypne"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index 199fad541958..2f929f788a03 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Bør holde indtil ca. <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Indtil <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Enheden løber muligvis tør for batteri inden <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Der er mere end <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Der er mere end <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonen lukker muligvis snart ned"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Denne tablet lukker muligvis snart ned"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Enheden lukker muligvis snart ned"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 3b2b2a84ddfb..7838a0c810db 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -194,7 +194,7 @@ <item msgid="581904787661470707">"Am schnellsten"</item> </string-array> <string name="choose_profile" msgid="343803890897657450">"Profil auswählen"</string> - <string name="category_personal" msgid="6236798763159385225">"Nutzer"</string> + <string name="category_personal" msgid="6236798763159385225">"Privat"</string> <string name="category_work" msgid="4014193632325996115">"Geschäftlich"</string> <string name="development_settings_title" msgid="140296922921597393">"Entwickleroptionen"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Entwickleroptionen aktivieren"</string> @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Sollte etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Bis <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Der Akku ist voraussichtlich um <xliff:g id="TIME">%1$s</xliff:g> leer"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Weniger als <xliff:g id="THRESHOLD">%1$s</xliff:g> verbleibend"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Weniger als <xliff:g id="THRESHOLD">%1$s</xliff:g> verbleibend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Mehr als <xliff:g id="TIME_REMAINING">%1$s</xliff:g> verbleibend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Mehr als <xliff:g id="TIME_REMAINING">%1$s</xliff:g> verbleibend"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Smartphone wird eventuell bald ausgeschaltet"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet wird eventuell bald ausgeschaltet"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Gerät wird eventuell bald ausgeschaltet"</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index 224e6ff4ee40..f617a93a4a6b 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Θα διαρκέσει μέχρι τις <xliff:g id="TIME">%1$s</xliff:g> περίπου"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Έως τις <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Η μπαταρία μπορεί να εξαντληθεί έως τις <xliff:g id="TIME">%1$s</xliff:g>."</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Απομένει/ουν λιγότερo/α από <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Απομένει/ουν λιγότερo/α από <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Απομένουν περισσότερα/ες από <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Απομένουν περισσότερα/ες από <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Το τηλέφωνο μπορεί να απενεργοποιηθεί σύντομα"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Το tablet μπορεί να απενεργοποιηθεί σύντομα"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Η συσκευή μπορεί να απενεργοποιηθεί σύντομα"</string> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index a932bceb02a5..f6d6d77c7bf4 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Battery may run out by <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Phone may shut down soon"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet may shut down soon"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Device may shut down soon"</string> diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index a932bceb02a5..f6d6d77c7bf4 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Battery may run out by <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Phone may shut down soon"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet may shut down soon"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Device may shut down soon"</string> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index a932bceb02a5..f6d6d77c7bf4 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Battery may run out by <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Phone may shut down soon"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet may shut down soon"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Device may shut down soon"</string> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index a932bceb02a5..f6d6d77c7bf4 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Battery may run out by <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Phone may shut down soon"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet may shut down soon"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Device may shut down soon"</string> diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index 6295fe6dd16c..b0424e22fb77 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -436,10 +436,10 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Battery may run out by <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining"</string> + <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> left"</string> + <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Phone may shut down soon"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet may shut down soon"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Device may shut down soon"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 11726aee16bd..dcfee98eabaf 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar aproximadamente hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Es posible que la batería se agote para las <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Es posible que pronto se apague el teléfono"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Es posible que pronto se apague la tablet"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Es posible que pronto se apague el dispositivo"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index d32f6a797522..e7a84751ca72 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -435,11 +435,15 @@ <string name="power_discharge_by" msgid="4113180890060388350">"Debería durar aproximadamente hasta <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar hasta las <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Es probable que te quedes sin batería sobre esta hora: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Queda menos del <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Queda más del <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Tiempo restante: más de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Puede que se agote la batería sobre las <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Es posible que el teléfono se apague pronto"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Es posible que el tablet se apague pronto"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Es posible que el dispositivo se apague pronto"</string> @@ -454,7 +458,7 @@ <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápidamente"</string> <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Cargando lentamente"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"No se está cargando"</string> - <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Se ha conectado, pero no se puede cargar en este momento"</string> + <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Enchufado, pero no se puede cargar en este momento"</string> <string name="battery_info_status_full" msgid="4443168946046847468">"Completa"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada por el administrador"</string> <string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index 73320100c2d6..f42111d1989b 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -420,7 +420,7 @@ <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Deuteranomaalia (punane-roheline)"</string> <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaalia (punane-roheline)"</string> <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaalia (sinine-kollane)"</string> - <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Värvikorrigeerimine"</string> + <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Värvide korrigeerimine"</string> <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"Värvikorrigeerimine võimaldab kohandada seadmes kuvatavaid värve"</string> <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Peaks kestma kuni <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Kuni <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Aku võib tühjaks saada kell <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Jäänud on alla <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Jäänud on alla <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Jäänud on üle <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Jäänud on üle <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon võib peagi välja lülituda"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tahvelarvuti võib peagi välja lülituda"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Seade võib peagi välja lülituda"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 321d6df4e9b1..85260fe01e26 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Ordu honetara arte iraungo du, gutxi gorabehera: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> arte"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baliteke bateria ordu honetan agortzea: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> baino gutxiago gelditzen dira"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g> baino gutxiago gelditzen da (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> baino gehiago gelditzen da (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> baino gehiago gelditzen da"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Baliteke telefonoa laster itzaltzea"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Baliteke tableta laster itzaltzea"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Baliteke gailua laster itzaltzea"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 1687e54ca071..6afa8898d3b1 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"باید حدوداً تا <xliff:g id="TIME">%1$s</xliff:g> شارژ داشته باشید"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"تا <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ممکن است باتری در <xliff:g id="TIME">%1$s</xliff:g> تمام شود"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"کمتر از <xliff:g id="THRESHOLD">%1$s</xliff:g> باقی مانده"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"کمتر از <xliff:g id="THRESHOLD">%1$s</xliff:g> شارژ باقی مانده است (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"بیش از <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"بیش از <xliff:g id="TIME_REMAINING">%1$s</xliff:g> باقی مانده است"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ممکن است تلفن بهزودی خاموش شود"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ممکن است رایانه لوحی بهزودی خاموش شود"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ممکن است دستگاه بهزودی خاموش شود"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index d75cc190fa5b..9e1fa76341ee 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Varaus loppuu noin <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> saakka"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Akku voi loppua <xliff:g id="TIME">%1$s</xliff:g> mennessä"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Alle <xliff:g id="THRESHOLD">%1$s</xliff:g> jäljellä"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Alle <xliff:g id="THRESHOLD">%1$s</xliff:g> jäljellä (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Yli <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Yli <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Puhelin voi sammua pian"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tabletti voi sammua pian"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Laite voi sammua pian"</string> @@ -508,7 +512,7 @@ <string name="alarm_template_far" msgid="6382760514842998629">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Kesto"</string> <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Kysy aina"</string> - <string name="zen_mode_forever" msgid="3339224497605461291">"Kunnes poistat sen käytöstä"</string> + <string name="zen_mode_forever" msgid="3339224497605461291">"Kunnes laitat pois päältä"</string> <string name="time_unit_just_now" msgid="3006134267292728099">"Äsken"</string> <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Puhelimen kaiutin"</string> <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Yhteysvirhe. Sammuta laite ja käynnistä se uudelleen."</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index fdace218857f..146fbe912dcd 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La pile risque d\'être épuisée à <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Il se peut que le téléphone s\'éteigne bientôt"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Il se peut que la tablette s\'éteigne bientôt"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Il se peut que l\'appareil s\'éteigne bientôt"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index 425a22bb13a1..c2a8d496d9eb 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -143,7 +143,7 @@ <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Applications supprimées"</string> <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Applications et utilisateurs supprimés"</string> <string name="data_usage_ota" msgid="7984667793701597001">"Mises à jour du système"</string> - <string name="tether_settings_title_usb" msgid="3728686573430917722">"Partage connexion Bluetooth par USB"</string> + <string name="tether_settings_title_usb" msgid="3728686573430917722">"Partage de connexion via USB"</string> <string name="tether_settings_title_wifi" msgid="4803402057533895526">"Point d\'accès Wi-Fi mobile"</string> <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Partage connexion Bluetooth"</string> <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Partage de connexion"</string> @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batterie risque d\'être épuisée à <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Le téléphone va bientôt s\'éteindre"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"La tablette va bientôt s\'éteindre"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"L\'appareil va bientôt s\'éteindre"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index bbc4e18754fe..2a6bcfc51c3a 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar aproximadamente ata a seguinte hora: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Ata: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"A batería pode esgotarse á seguinte hora: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Tempo restante inferior a <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Tempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Tempo restante: máis de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Tempo restante: máis de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"O teléfono pode apagarse en breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"A tableta pode apagarse en breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"O dispositivo pode apagarse en breve"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 94d4c9231c4e..4be85c7ddc9c 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"बैटरी करीब <xliff:g id="TIME">%1$s</xliff:g> तक चलेगी"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> तक"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"बैटरी <xliff:g id="TIME">%1$s</xliff:g> तक खत्म हो जाएगी"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> से कम समय बचा है"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g> से कम बैटरी बची है (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> से ज़्यादा चलने लायक बैटरी बची है (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> से ज़्यादा चलने लायक बैटरी बची है"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"फ़ोन जल्द ही बंद हो सकता है"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"टैबलेट जल्द ही बंद हो सकता है"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"डिवाइस जल्द ही बंद हो सकता है"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index 9dcdf0e9c0de..115fef8c7b27 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Trebala bi trajati do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterija bi se mogla isprazniti do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Preostalo je manje od <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Preostalo je više od <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon bi se uskoro mogao isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet bi se uskoro mogao isključiti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Uređaj bi se uskoro mogao isključiti"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 15f008bcb1f7..a223b4d03b2a 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Nagyjából eddig bírja: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Eddig: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Az akkumulátor lemerülhet a következő időpontig: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Kevesebb mint <xliff:g id="TIME_REMAINING">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Több mint <xliff:g id="TIME_REMAINING">%1$s</xliff:g> van hátra"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Előfordulhat, hogy a telefon hamarosan kikapcsol"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Előfordulhat, hogy a táblagép hamarosan kikapcsol"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Előfordulhat, hogy az eszköz hamarosan kikapcsol"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index b1639b59c980..8d40abc9ab72 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Լիցքը պետք է որ բավականացնի մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Մարտկոցի լիցքը կարող է սպառվել մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից պակաս"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից պակաս (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Մնացել է ավելի քան <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Մնացել է ավելի քան <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Հեռախոսը շուտով կանջատվի"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Պլանշետը շուտով կանջատվի"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Սարքը շուտով կանջատվի"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 3d18da0f9540..3f11da392673 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Akan bertahan kira-kira sampai pukul <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hingga <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterai mungkin habis pada <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Tersisa kurang dari <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Tersisa kurang dari <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Tersisa lebih dari <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Tersisa lebih dari <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Ponsel akan segera dimatikan"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet akan segera dimatikan"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Perangkat akan segera dimatikan"</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index 17c6fec27d79..d925df3a8239 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Ætti að endast til u.þ.b. <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Til klukkan <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Rafhlaðan gæti tæmst kl. <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Minna en <xliff:g id="THRESHOLD">%1$s</xliff:g> eftir"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Minna en <xliff:g id="THRESHOLD">%1$s</xliff:g> eftir (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Meira en <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Meira en <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Síminn gæti slökkt á sér fljótlega"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Spjaldtölvan gæti slökkt á sér fljótlega"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Tækið gæti slökkt á sér fljótlega"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index e4883be16bf8..3f385974bb9e 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Ora stimata esaurimento batteria: <xliff:g id="TIME">%1$s</xliff:g> circa"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Fino alle ore <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batteria potrebbe esaurirsi entro <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Tempo rimanente: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Tempo rimanente: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Tempo rimanente: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Tempo rimanente: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Il telefono potrebbe spegnersi a breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Il tablet potrebbe spegnersi a breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Il dispositivo potrebbe spegnersi a breve"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index da17dd750ef6..53f82eba9c39 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"אמורה להחזיק מעמד בערך עד <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"עד <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ייתכן שהסוללה תתרוקן עד <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"נותרו פחות מ-<xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"נותרו פחות מ-<xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"נותרו יותר מ-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"הזמן שנותר: יותר מ-<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"הטלפון עלול להיכבות בקרוב"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"הטאבלט עלול להיכבות בקרוב"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"המכשיר עלול להיכבות בקרוב"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index ef41da3cb7f5..2f91ea639263 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"電池が切れる推定時刻: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> まで"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> 頃に電池がなくなります"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"残り時間: <xliff:g id="THRESHOLD">%1$s</xliff:g>未満"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"残り時間: <xliff:g id="THRESHOLD">%1$s</xliff:g>未満(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"残り時間: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>以上(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"残り時間: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>以上"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"スマートフォンの電源がもうすぐ切れます"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"タブレットの電源がもうすぐ切れます"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"デバイスの電源がもうすぐ切れます"</string> @@ -506,7 +510,7 @@ <string name="zen_alarm_warning" msgid="245729928048586280">"次回のアラーム(<xliff:g id="WHEN">%1$s</xliff:g>)は鳴りません"</string> <string name="alarm_template" msgid="3346777418136233330">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="6382760514842998629">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> - <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"期間"</string> + <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"時間"</string> <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"毎回確認"</string> <string name="zen_mode_forever" msgid="3339224497605461291">"OFF にするまで"</string> <string name="time_unit_just_now" msgid="3006134267292728099">"たった今"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index 4e28c5bf6a4a..21ebcedd496c 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"უნდა იმუშაოს დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>-მდე"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g>-მდე"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ბატარეა შესაძლოა ამოიწუროს <xliff:g id="TIME">%1$s</xliff:g>-ისთვის"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"დარჩენილია <xliff:g id="THRESHOLD">%1$s</xliff:g>-ზე ნაკლები"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"დარჩენილია <xliff:g id="THRESHOLD">%1$s</xliff:g>-ზე ნაკლები დრო (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"დარჩენილია <xliff:g id="TIME_REMAINING">%1$s</xliff:g>-ზე მეტი დრო (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"დარჩენილია <xliff:g id="TIME_REMAINING">%1$s</xliff:g>-ზე მეტი დრო"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ტელეფონი შეიძლება მალე გათიშოს"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ტაბლეტი შეიძლება მალე გაითიშოს"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"მოწყობილობა შეიძლება მალე გაითიშოს"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index a9f2a1b923de..f33a094ba584 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Шамамен <xliff:g id="TIME">%1$s</xliff:g> дейін жетеді"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> дейін"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарея заряды <xliff:g id="TIME">%1$s</xliff:g> сағатқа қарай бітуі мүмкін."</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> шамасынан аз қалды"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g> шамасынан аз қалды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> шамасынан көп уақыт қалды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> шамасынан көп уақыт қалды"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон көп ұзамай өшуі мүмкін"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет көп ұзамай өшуі мүмкін"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Құрылғы көп ұзамай өшуі мүмкін"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 0e566c1d818c..aa5205264942 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"គួរតែអាចប្រើបានរហូតដល់ម៉ោងប្រហែល <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"រហូតដល់ម៉ោង <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"អាចនឹងអស់ថ្មត្រឹមម៉ោង <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"នៅសល់តិចជាង <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"នៅសល់តិចជាង <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"នៅសល់ច្រើនជាង <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"នៅសល់ច្រើនជាង <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ទូរសព្ទអាចនឹងបិទក្នុងពេលបន្តិចទៀត"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ថេប្លេតអាចនឹងបិទក្នុងពេលបន្តិចទៀត"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ឧបករណ៍អាចនឹងបិទក្នុងពេលបន្តិចទៀត"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index 4e873be8dada..aece31fb1ef6 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"<xliff:g id="TIME">%1$s</xliff:g> ಸಮಯದವರೆಗೆ ಫೋನ್ ರನ್ ಆಗಬೇಕು"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> ರವರೆಗೆ"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> ಗಳಲ್ಲಿ ಬ್ಯಾಟರಿ ಮುಕ್ತಾಯವಾಗಬಹುದು"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ನಿಮಿಷಕ್ಕಿಂತ ಕಡಿಮೆ ಸಮಯ ಉಳಿದಿದೆ"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ಕ್ಕಿಂತ ಕಡಿಮೆ (<xliff:g id="LEVEL">%2$s</xliff:g>) ಬಾಕಿ"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು (<xliff:g id="LEVEL">%2$s</xliff:g>) ಬಾಕಿ"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಸಮಯ ಉಳಿದಿದೆ"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ಫೋನ್ ಶೀಘ್ರದಲ್ಲೇ ಶಟ್ ಡೌನ್ ಆಗಬಹುದು"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ಟ್ಯಾಬ್ಲೆಟ್ ಶೀಘ್ರದಲ್ಲೇ ಶಟ್ ಡೌನ್ ಆಗಬಹುದು"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ಸಾಧನವು ಶೀಘ್ರದಲ್ಲೇ ಶಟ್ ಡೌನ್ ಆಗಬಹುದು"</string> @@ -535,7 +539,7 @@ <string name="user_add_user_title" msgid="5457079143694924885">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸುವುದೇ?"</string> <string name="user_add_user_message_long" msgid="1527434966294733380">"ನೀವು ಹೆಚ್ಚುವರಿ ಬಳಕೆದಾರರನ್ನು ರಚಿಸುವ ಮೂಲಕ ಇತರ ಜನರ ಜೊತೆಗೆ ಈ ಸಾಧನವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು. ಪ್ರತಿ ಬಳಕೆದಾರರು ತಮ್ಮದೇ ಸ್ಥಳವನ್ನು ಹೊಂದಿರುತ್ತಾರೆ, ಇದರಲ್ಲಿ ಅವರು ತಮ್ಮದೇ ಅಪ್ಲಿಕೇಶನ್ಗಳು, ವಾಲ್ಪೇಪರ್ ಮತ್ತು ಮುಂತಾದವುಗಳ ಮೂಲಕ ಕಸ್ಟಮೈಸ್ ಮಾಡಿಕೊಳ್ಳಬಹುದು. ಎಲ್ಲರ ಮೇಲೂ ಪರಿಣಾಮ ಬೀರುವಂತೆ ವೈ-ಫೈ ರೀತಿಯ ಸಾಧನ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬಳಕೆದಾರರು ಸರಿಹೊಂದಿಸಬಹುದು.\n\nನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಹೊಂದಿಸಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗೆ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಬಹುದು. ಪ್ರವೇಶಿಸುವಿಕೆ ಸೆಟ್ಟಿಂಗ್ಗಳು ಮತ್ತು ಸೇವೆಗಳು ಹೊಸ ಬಳಕೆದಾರರಿಗೆ ವರ್ಗಾವಣೆ ಆಗದಿರಬಹುದು."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"ನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಸ್ಥಾಪಿಸಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಬಹುದು."</string> - <string name="user_setup_dialog_title" msgid="8037342066381939995">"ಈಗ ಬಳಕೆದಾರರನ್ನು ಸೆಟಪ್ ಮಾಡುವುದೇ?"</string> + <string name="user_setup_dialog_title" msgid="8037342066381939995">"ಈಗ ಬಳಕೆದಾರರನ್ನು ಸೆಟ್ ಮಾಡುವುದೇ?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"ಸಾಧನವನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ಮತ್ತು ಅದರ ಸ್ಥಳವನ್ನು ಹೊಂದಿಸಲು ವ್ಯಕ್ತಿಯು ಲಭ್ಯವಿದ್ದಾರೆಯೇ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ಇದೀಗ ಪ್ರೊಫೈಲ್ ಅನ್ನು ಹೊಂದಿಸುವುದೇ?"</string> <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ಇದೀಗ ಹೊಂದಿಸಿ"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 85304400ed7c..9dbeb45cea8e 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"대략 <xliff:g id="TIME">%1$s</xliff:g>까지 사용 가능"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g>까지"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"예상 배터리 종료 시간: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> 미만 남음"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g> 미만 남음(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> 이상 남음(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> 이상 남음"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"휴대전화가 곧 종료될 수 있음"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"태블릿이 곧 종료될 수 있음"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"기기가 곧 종료될 수 있음"</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index fc6343531d6f..66c5c4fb09f5 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Болжол менен саат <xliff:g id="TIME">%1$s</xliff:g> өчөт"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> чейин"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарея <xliff:g id="TIME">%1$s</xliff:g> отуруп калышы мүмкүн"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> жетпеген убакыт калды"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g> жетпеген убакыт калды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ашыгыраак убакыт калды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ашыгыраак убакыт калды"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон бир аздан кийин өчүп калышы мүмкүн"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет бир аздан кийин өчүп калышы мүмкүн"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Түзмөк бир аздан кийин өчүп калышы мүмкүн"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 5d4efe28430b..f5816b33162a 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"ໜ້າຈະໃຊ້ໄດ້ຈົນຮອດປະມານ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"ຈົນກວ່າຈະຮອດ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ແບັດເຕີຣີອາດຈະໝົດພາຍໃນເວລາ <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"ຍັງເຫຼືອໜ້ອຍກວ່າ <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"ຍັງເຫຼືອໜ້ອຍກວ່າ <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"ຍັງເຫຼືອຫຼາຍກວ່າ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"ຍັງເຫຼືອຫຼາຍກວ່າ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ໂທລະສັບອາດປິດໃນໄວໆນີ້"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ແທັບເລັດອາດປິດໃນໄວໆນີ້"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ອຸປະກອນອາດປິດໃນໄວໆນີ້"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index e2ccc3a30877..4772124307f6 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Turėtų išsikrauti maždaug po <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Iki <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Akumuliatoriaus energija gali išsekti <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Liko mažiau nei <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Liko mažiau nei <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Liko daugiau nei <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Liko daugiau nei <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonas netrukus gali būti išjungtas"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Planšetinis komp. netrukus gali būti išjungtas"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Įrenginys netrukus gali būti išjungtas"</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index 64368b7b0e95..9b9da06f0c08 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Darbosies aptuveni līdz <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Līdz <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Iespējams, akumulators izlādēsies līdz <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Atlikušais laiks — mazāk nekā <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Atlicis mazāk nekā <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Atlicis vairāk nekā <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Atlicis vairāk nekā <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Tālrunis, iespējams, drīz izslēgsies."</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Planšetdators, iespējams, drīz izslēgsies."</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Ierīce, iespējams, drīz izslēgsies."</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index e285abdbd22a..c272c5a4e06d 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Треба да трае до околу <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Може да снема батерија до <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Уште помалку од <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Уште помалку од <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Уште повеќе од <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Уште повеќе од <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон може да се исклучи наскоро"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Таблетот може да се исклучи наскоро"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Уредот може да се исклучи наскоро"</string> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 7ab2bbb4b5fe..f61c44cd4440 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -156,7 +156,7 @@ <string name="launch_defaults_none" msgid="8049374306261262709">"സ്ഥിരമായൊന്നും സജ്ജീകരിച്ചിട്ടില്ല"</string> <string name="tts_settings" msgid="8130616705989351312">"ടെക്സ്റ്റ്-ടു-സ്പീച്ച് ക്രമീകരണങ്ങൾ"</string> <string name="tts_settings_title" msgid="7602210956640483039">"ടെക്സ്റ്റ്-ടു-സ്പീച്ച് ഔട്ട്പുട്ട്"</string> - <string name="tts_default_rate_title" msgid="3964187817364304022">"വായനാ നിരക്ക്"</string> + <string name="tts_default_rate_title" msgid="3964187817364304022">"വായനയുടെ വേഗത"</string> <string name="tts_default_rate_summary" msgid="3781937042151716987">"ടെക്സ്റ്റ് ചെയ്യൽ പറയുമ്പോഴുടെക്കുന്ന വേഗത"</string> <string name="tts_default_pitch_title" msgid="6988592215554485479">"പിച്ച്"</string> <string name="tts_default_pitch_summary" msgid="9132719475281551884">"സിന്തസൈസ് ചെയ്ത സംസാരത്തിന്റെ സ്വരഭേദത്തെ ബാധിക്കുന്നു"</string> @@ -178,7 +178,7 @@ <string name="tts_status_checking" msgid="8026559918948285013">"പരിശോധിക്കുന്നു…"</string> <string name="tts_engine_settings_title" msgid="7849477533103566291">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> എന്നതിനായുള്ള ക്രമീകരണങ്ങൾ"</string> <string name="tts_engine_settings_button" msgid="477155276199968948">"എഞ്ചിൻ ക്രമീകരണങ്ങൾ സമാരംഭിക്കുക"</string> - <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"തിരഞ്ഞെടുത്ത എഞ്ചിൻ"</string> + <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"മുൻഗണന നൽകുന്ന എഞ്ചിൻ"</string> <string name="tts_general_section_title" msgid="8919671529502364567">"പൊതുവായ കാര്യങ്ങൾ"</string> <string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"സംസാരത്തിന്റെ ശബ്ദനില പുനഃക്രമീകരിക്കുക"</string> <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"ടെക്സ്റ്റ് സംസാരിക്കപ്പെടുന്ന ശബ്ദനില \'ഡിഫോൾട്ടി\'ലേക്ക് പുനഃക്രമീകരിക്കുക."</string> @@ -420,8 +420,8 @@ <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"വർണ്ണാന്ധത (ചുവപ്പ്-പച്ച)"</string> <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"പ്രോട്ടാനോമലി (ചുവപ്പ്-പച്ച)"</string> <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ട്രിട്ടാനോമലി (നീല-മഞ്ഞ)"</string> - <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"വർണ്ണം ക്രമീകരിക്കൽ"</string> - <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"നിങ്ങളുടെ ഉപകരണത്തിൽ നിറങ്ങൾ എങ്ങനെ പ്രദർശിപ്പിക്കുന്നു എന്നത് ക്രമീകരിക്കാൻ നിറം തിരുത്തൽ അനുവദിക്കുന്നു"</string> + <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"നിറം ക്രമീകരിക്കൽ"</string> + <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"നിങ്ങളുടെ ഉപകരണത്തിൽ നിറങ്ങൾ എങ്ങനെ പ്രദർശിപ്പിക്കുന്നു എന്നത് ക്രമീകരിക്കാൻ \'നിറം ക്രമീകരിക്കൽ\' അനുവദിക്കുന്നു"</string> <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="8264199158671531431">"ഏതാണ്ട് <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ശേഷിക്കുന്നു"</string> @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"ഏകദേശം <xliff:g id="TIME">%1$s</xliff:g> വരെ നീണ്ടുനിൽക്കേണ്ടതാണ്"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> വരെ"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> ആവുമ്പോഴേക്ക് ബാറ്ററി തീർന്നേക്കാം"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-ൽ കുറവ് സമയം ശേഷിക്കുന്നു"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-ൽ കുറവ് സമയം ശേഷിക്കുന്നു (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-ൽ കൂടുതൽ സമയം ശേഷിക്കുന്നു (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-ൽ കൂടുതൽ സമയം ശേഷിക്കുന്നു"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ഫോൺ ഉടൻ ഷട്ട് ഡൗൺ ആയേക്കാം"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ടാബ്ലെറ്റ് ഉടൻ ഷട്ട് ഡൗൺ ആയേക്കാം"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ഉപകരണം ഉടൻ ഷട്ട് ഡൗൺ ആയേക്കാം"</string> @@ -533,7 +537,7 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"ഉപയോക്താവ്"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"നിയന്ത്രിത പ്രൊഫൈൽ"</string> <string name="user_add_user_title" msgid="5457079143694924885">"പുതിയ ഉപയോക്താവിനെ ചേർക്കണോ?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"കൂടുതൽ ഉപയോക്താക്കളെ സൃഷ്ടിച്ചുകൊണ്ട് ഈ ഉപകരണം മറ്റുള്ളവരുമായി നിങ്ങൾക്ക് പങ്കിടാം. ആപ്പുകളും വാൾപേപ്പറുകളും മറ്റും ഉപയോഗിച്ച് ഇഷ്ടാനുസൃതമാക്കാൻ ഓരോ ഉപയോക്താവിനും സാധിക്കും. വൈഫൈ പോലെ എല്ലാവരെയും ബാധിക്കുന്ന ഉപകരണ ക്രമീകരണവും ഉപയോക്താക്കൾക്ക് ക്രമീകരിക്കാം.\n\nനിങ്ങളൊരു പുതിയ ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തിക്ക് സ്വന്തമായ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\n എല്ലാ ഉപയോക്താക്കൾക്കുമായി ആപ്പുകൾ അപ്ഡേറ്റ് ചെയ്യാൻ ഏതൊരു ഉപയോക്താവിനുമാവും. ഉപയോഗസഹായി ക്രമീകരണവും സേവനങ്ങളും പുതിയ ഉപയോക്താവിന് കൈമാറിയേക്കില്ല."</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"കൂടുതൽ ഉപയോക്താക്കളെ സൃഷ്ടിച്ചുകൊണ്ട് ഈ ഉപകരണം മറ്റുള്ളവരുമായി നിങ്ങൾക്ക് പങ്കിടാം. ആപ്പുകളും വാൾപേപ്പറുകളും മറ്റും ഉപയോഗിച്ച് ഇഷ്ടാനുസൃതമാക്കാൻ ഓരോ ഉപയോക്താവിനും സാധിക്കും. വൈഫൈ പോലെ എല്ലാവരെയും ബാധിക്കുന്ന ഉപകരണ ക്രമീകരണവും ഉപയോക്താക്കൾക്ക് ക്രമീകരിക്കാം.\n\nനിങ്ങളൊരു പുതിയ ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തിക്ക് സ്വന്തമായ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\n എല്ലാ ഉപയോക്താക്കൾക്കുമായി ആപ്പുകൾ അപ്ഡേറ്റ് ചെയ്യാൻ ഏതൊരു ഉപയോക്താവിനുമാവും. ഉപയോഗസഹായി ക്രമീകരണവും സേവനങ്ങളും പുതിയ ഉപയോക്താവിന് കൈമാറുകയില്ല."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"നിങ്ങൾ ഒരു പുതിയ ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തിയ്ക്ക് അവരുടെ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\nമറ്റ് എല്ലാ ഉപയോക്താക്കൾക്കുമായി ഏതൊരു ഉപയോക്താവിനും അപ്ലിക്കേഷനുകൾ അപ്ഡേറ്റുചെയ്യാനാവും."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"ഉപയോക്താവിനെ ഇപ്പോൾ സജ്ജീകരിക്കണോ?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"ഉപകരണം എടുത്ത് ഇടം സജ്ജീകരിക്കുന്നതിന് വ്യക്തി ലഭ്യമാണെന്ന് ഉറപ്പാക്കുക"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 7ed1078139ad..33806451220b 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> хүртэл барих ёстой"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> хүртэл"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарейн цэнэг <xliff:g id="TIME">%1$s</xliff:g> гээд дуусаж болзошгүй"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-с бага хугацаа үлдсэн"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g>-с бага хугацаа үлдсэн (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-с их хугацаа үлдсэн (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>-с их хугацаа үлдсэн"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Утас удахгүй унтарч болзошгүй"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Таблет удахгүй унтарч болзошгүй"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Төхөөрөмж удахгүй унтарч болзошгүй"</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index 09a558db495f..294ab2743054 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Seharusnya boleh digunakan hingga kira-kira <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hingga <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateri mungkin kehabisan selewat-lewatnya <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Tinggal kurang daripada <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Kurang daripada <xliff:g id="THRESHOLD">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Lebih daripada <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Lebih daripada <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon mungkin ditutup tidak lama lagi"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet mungkin ditutup tidak lama lagi"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Peranti mungkin ditutup tidak lama lagi"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index 27b1a2c0d143..7525a0fe9e05 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"<xliff:g id="TIME">%1$s</xliff:g> ခန့်အထိ သုံးနိုင်သည်"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> အထိ"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> တွင် ဘက်ထရီကုန်သွားနိုင်သည်"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ခန့်သာ ကျန်တော့သည်"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g> အောက်သာ ကျန်သည် (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ကျော် ကျန်သည် (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ကျော် ကျန်သေးသည်"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"မကြာမီ ဖုန်းပိတ်သွားနိုင်သည်"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"မကြာမီ တက်ဘလက် ပိတ်သွားနိုင်သည်"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"မကြာမီ စက်ပိတ်သွားနိုင်သည်"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index cc883ab1e63d..3f3877110f14 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Skal vare til omtrent <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Til <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batteriet kan gå tomt <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Mindre enn <xliff:g id="THRESHOLD">%1$s</xliff:g> gjenstår"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Mindre enn <xliff:g id="THRESHOLD">%1$s</xliff:g> gjenstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Mer enn <xliff:g id="TIME_REMAINING">%1$s</xliff:g> gjenstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Mer enn <xliff:g id="TIME_REMAINING">%1$s</xliff:g> gjenstår"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonen slås kanskje av snart"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Nettbrettet slås kanskje av snart"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Enheten slås kanskje av snart"</string> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index 60942242f00a..200e0ec33c6e 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -438,10 +438,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"लगभग <xliff:g id="TIME">%1$s</xliff:g> सम्म टिक्नु पर्छ"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> सम्म"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ब्याट्री <xliff:g id="TIME">%1$s</xliff:g> बजेसम्ममा सकिन सक्छ"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> भन्दा कम समय बाँकी छ"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g> भन्दा कम समय बाँकी (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> भन्दा बढी समय बाँकी (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> भन्दा बढी समय बाँकी"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"फोन चाँडै बन्द हुन सक्छ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ट्याब्लेट चाँडै बन्द हुन सक्छ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"यन्त्र चाँडै बन्द हुन सक्छ"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index c566dc23d2b0..176a8b7ca5cf 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -235,7 +235,7 @@ <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Maak verbinding met een wifi-netwerk"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, foutopsporing, ontwikkeling"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Snelle link naar bugrapport"</string> - <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Een knop in het voedingsmenu weergeven om een bugrapport te maken"</string> + <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Een knop in het aan/uit-menu weergeven om een bugrapport te maken"</string> <string name="keep_screen_on" msgid="1187161672348797558">"Stand-by"</string> <string name="keep_screen_on_summary" msgid="1510731514101925829">"Scherm gaat nooit uit tijdens het opladen"</string> <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Snoop-logbestand voor Bluetooth-HCI inschakelen"</string> @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Is nog genoeg tot ongeveer <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Tot <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batterij is waarschijnlijk leeg om <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Nog minder dan <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Nog minder dan <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Nog meer dan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Nog meer dan <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefoon wordt binnenkort mogelijk uitgeschakeld"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet wordt binnenkort mogelijk uitgeschakeld"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Apparaat wordt binnenkort mogelijk uitgeschakeld"</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index b3ee2e3e8eb4..a38a3ea253ff 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -251,8 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"ୱାୟରଲେସ୍ ଡିସ୍ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"ୱାଇ-ଫାଇ ଭର୍ବୋସ୍ ଲଗିଙ୍ଗ ସକ୍ଷମ କରନ୍ତୁ"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"ୱାଇ-ଫାଇ ସ୍କାନ୍ ନିୟନ୍ତ୍ରଣ"</string> - <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> - <skip /> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"ୱାଇ‑ଫାଇ-ଉନ୍ନତ MAC ରେଣ୍ଡମାଇଜେସନ୍"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"ମୋବାଇଲ୍ ଡାଟା ସର୍ବଦା ସକ୍ରିୟ"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ଆକ୍ସିଲିରେସନ୍"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"ବ୍ଲୁଟୂଥ୍ ଡିଭାଇସ୍ଗୁଡ଼ିକୁ ନାମ ବିନା ଦେଖନ୍ତୁ"</string> @@ -285,8 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ୱେୟାରଲେସ୍ ଡିସ୍ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍ ପାଇଁ ବିକଳ୍ପ ଦେଖାନ୍ତୁ"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"ୱାଇ-ଫାଇ ଲଗିଙ୍ଗ ସ୍ତର ବଢ଼ାନ୍ତୁ, ୱାଇ-ଫାଇ ପିକର୍ରେ ପ୍ରତି SSID RSSI ଦେଖାନ୍ତୁ"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ବ୍ୟାଟେରୀ ଖର୍ଚ୍ଚ କମ୍ ଏବଂ ନେଟ୍ୱାର୍କ କାର୍ଯ୍ୟକ୍ଷମତା ଉନ୍ନତ କରିଥାଏ"</string> - <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> - <skip /> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"ଏହି ଟୋଗଲ୍ କେବଳ କ୍ଲାଏଣ୍ଟ ମୋଡ୍ ପାଇଁ MAC ରେଣ୍ଡମାଇଜେସନ୍ ବ୍ୟବହାରକୁ ପ୍ରଭାବିତ କରେ।\nଯେତେବେଳେ ଏହି ମୋଡକୁ ସକ୍ରିୟ କରାଯାଏ, ସେତେବେଳେ କ୍ଲାଏଣ୍ଟ ଗତଥର କେତେବେଳେ ନେଟୱାର୍କରୁ ସଂଯୋଗ ବିଚ୍ଛିନ୍ନ କରିଥିଲେ ତାହା ଉପରେ ନିର୍ଭର କରି, MAC ରେଣ୍ଡମାଇଜେସନ୍ ସକ୍ଷମ କରାଯାଇଥିବା ଯେ କୌଣସି ନେଟୱାର୍କର MAC ଠିକଣାଗୁଡ଼ିକୁ ସଂଯୋଜନ ସମୟରେ ପୁଣି ରେଣ୍ଡମାଇଜ୍ କରାଯାଇପାରେ। ଯଦି ଡିଭାଇସଟି 4 ଘଣ୍ଟା କିମ୍ବା ତାଠାରୁ କମ୍ ସମୟରେ ପୁଣି ସଂଯୋଗ କରେ, ତେବେ ପୁଣି ରେଣ୍ଡମାଇଜେସନ୍ ହୁଏ ନାହିଁ।"</string> <string name="wifi_metered_label" msgid="8737187690304098638">"ମପାଯାଉଥିବା"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"ମପାଯାଉନଥିବା"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"ଲଗର୍ ବଫର୍ ସାଇଜ୍"</string> @@ -438,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"ବ୍ୟାଟେରୀ <xliff:g id="TIME">%1$s</xliff:g> ପର୍ଯ୍ୟନ୍ତ ଚାଲିବ"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> ପର୍ଯ୍ୟନ୍ତ"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> ସୁଦ୍ଧା ବ୍ୟାଟେରୀର ଚାର୍ଜ ଶେଷ ହୋଇ ଯାଇପାରେ"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g>ରୁ କମ୍ ସମୟ ବଳକା ଅଛି"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ରୁ କମ୍ ସମୟ ବଳକା ଅଛି (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>ରୁ ଅଧିକ ସମୟ ବଳକା ଅଛି(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>ରୁ ଅଧିକ ବଳକା ଅଛି"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ଫୋନ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯାଇପାରେ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ଟାବଲେଟ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯାଇପାରେ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ଡିଭାଇସ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯାଇପାରେ"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 138c72d45077..4ba370b3a030 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਤੱਕ ਚੱਲੇਗੀ"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> ਤੱਕ"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"ਬੈਟਰੀ <xliff:g id="TIME">%1$s</xliff:g> ਤੱਕ ਖਤਮ ਹੋ ਸਕਦੀ ਹੈ"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ਤੋਂ ਘੱਟ ਸਮਾਂ ਬਾਕੀ"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ਤੋਂ ਘੱਟ ਸਮਾਂ ਬਾਕੀ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਤੋਂ ਵੱਧ ਸਮਾਂ ਬਾਕੀ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਤੋਂ ਵੱਧ ਸਮਾਂ ਬਾਕੀ"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ਫ਼ੋਨ ਛੇਤੀ ਹੀ ਬੰਦ ਹੋ ਸਕਦਾ ਹੈ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ਟੈਬਲੈੱਟ ਛੇਤੀ ਹੀ ਬੰਦ ਹੋ ਸਕਦਾ ਹੈ"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"ਡੀਵਾਈਸ ਛੇਤੀ ਹੀ ਬੰਦ ਹੋ ਸਕਦਾ ਹੈ"</string> @@ -543,7 +547,7 @@ <string name="user_add_user_type_title" msgid="551279664052914497">"ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="user_new_user_name" msgid="60979820612818840">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string> <string name="user_new_profile_name" msgid="2405500423304678841">"ਨਵੀਂ ਪ੍ਰੋਫਾਈਲ"</string> - <string name="user_info_settings_title" msgid="6351390762733279907">"ਉਪਭੋਗਤਾ ਜਾਣਕਾਰੀ"</string> + <string name="user_info_settings_title" msgid="6351390762733279907">"ਵਰਤੋਂਕਾਰ ਜਾਣਕਾਰੀ"</string> <string name="profile_info_settings_title" msgid="105699672534365099">"ਪ੍ਰੋਫਾਈਲ ਜਾਣਕਾਰੀ"</string> <string name="user_need_lock_message" msgid="4311424336209509301">"ਇਸਤੋਂ ਪਹਿਲਾਂ ਕਿ ਤੁਸੀਂ ਇੱਕ ਪ੍ਰਤਿਬੰਧਿਤ ਪ੍ਰੋਫਾਈਲ ਬਣਾ ਸਕੋ, ਤੁਹਾਨੂੰ ਆਪਣੀਆਂ ਐਪਾਂ ਅਤੇ ਨਿੱਜੀ ਡਾਟਾ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਇੱਕ ਸਕ੍ਰੀਨ ਲਾਕ ਸੈੱਟ ਅੱਪ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।"</string> <string name="user_set_lock_button" msgid="1427128184982594856">" ਲਾਕ ਸੈੱਟ ਕਰੋ"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 023b3269d68f..d371c5254708 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Powinno wystarczyć do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateria może się wyczerpać do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Pozostało ponad: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Pozostało ponad: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Wkrótce telefon może się wyłączyć"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet może się wkrótce wyłączyć"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Urządzenie może się wkrótce wyłączyć"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 0b239a583f09..9124958af7b4 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Deve durar até por volta de <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Até <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"A bateria pode acabar neste horário: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> restante(s)"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> restante(s) (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Mais de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> restante(s) (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Mais de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> restante(s)"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"O smartphone pode ser desligado em breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"O tablet pode ser desligado em breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"O dispositivo pode ser desligado em breve"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index a008504420c6..6082965cac25 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Deve durar até cerca da(s) <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Até à(s) <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Poderá ficar sem bateria à(s) <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Resta(m) menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>."</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Resta(m) menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Resta(m) mais de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Resta(m) mais de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>."</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"O telemóvel poderá ser encerrado em breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"O tablet poderá ser encerrado em breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"O dispositivo poderá ser encerrado em breve"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 0b239a583f09..9124958af7b4 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Deve durar até por volta de <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Até <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"A bateria pode acabar neste horário: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> restante(s)"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> restante(s) (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Mais de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> restante(s) (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Mais de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> restante(s)"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"O smartphone pode ser desligado em breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"O tablet pode ser desligado em breve"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"O dispositivo pode ser desligado em breve"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index b0d78cde0ae8..fa43c13c7ccb 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Ar trebui să reziste până la <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Până la <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateria se poate descărca până la <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"a mai rămas mai puțin de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"A mai rămas mai puțin de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"A mai rămas mai mult de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"A mai rămas mai mult de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonul se poate închide în curând"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tableta se poate închide în curând"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Dispozitivul se poate închide în curând"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index a375bdbadd16..bb060711cf17 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Заряда хватит примерно до <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батарея может разрядиться к <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Осталось менее <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Уровень заряда батареи: <xliff:g id="LEVEL">%2$s</xliff:g> (хватит менее чем на <xliff:g id="THRESHOLD">%1$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Уровень заряда батареи: <xliff:g id="LEVEL">%2$s</xliff:g> (хватит более чем на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Хватит более чем на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон скоро выключится"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет скоро выключится"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Устройство скоро выключится"</string> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index d22a643a7856..9595bd19a7a2 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"<xliff:g id="TIME">%1$s</xliff:g> පමණ වන තෙක් තිබිය යුතුය"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> දක්වා"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"බැටරි බලය <xliff:g id="TIME">%1$s</xliff:g> වන විට අවසන් විය හැකිය"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g>ට වඩා අඩුවෙන් ඉතිරිව ඇත"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g>ට වඩා අඩුවෙන් ඉතිරිය (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>ට වඩා වැඩියෙන් ඉතිරිය (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>කට වඩා වැඩියෙන් ඉතිරිය"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"දුරකථනය ඉක්මනින් වැසිය හැකිය"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"ටැබ්ලට් පරිගණකය ඉක්මනින් වැසිය හැකිය"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"උපාංගය ඉක්මනින් වැසිය හැකිය"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index c6ea18b79a67..ea8cf7313d91 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batéria sa môže do <xliff:g id="TIME">%1$s</xliff:g> minúť"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Zostáva menej ako <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Zostáva menej ako <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Zostáva viac ako <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Zostáva viac ako <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefón sa môže čoskoro vypnúť"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet sa môže čoskoro vypnúť"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Zariadenie sa môže čoskoro vypnúť"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 1c83a7fe5a6a..893b20739717 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Moralo bi zadostovati do približno <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Energije baterije lahko zmanjka do <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Preostalo manj kot <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Preostanek: manj kot <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Preostali čas delovanja: manj kot <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Preostali čas delovanja: več kot <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon se bo morda kmalu zaustavil"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablični računalnik se bo morda kmalu zaustavil"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Naprava se bo morda kmalu zaustavila"</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index 2a50f5854eac..4debe7479973 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Duhet të zgjasë deri në rreth <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Deri në <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateria mund të mbarojë deri në <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Më pak se <xliff:g id="THRESHOLD">%1$s</xliff:g> të mbetura"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Mbeten më pak se <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Mbeten më shumë se <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Mbeten më shumë se <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefoni mund të fiket së shpejti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tableti mund të fiket së shpejti"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Pajisja mund të fiket së shpejti"</string> @@ -470,7 +474,7 @@ <string name="charge_length_format" msgid="6941645744588690932">"<xliff:g id="ID_1">%1$s</xliff:g> më parë"</string> <string name="remaining_length_format" msgid="4310625772926171089">"<xliff:g id="ID_1">%1$s</xliff:g> të mbetura"</string> <string name="screen_zoom_summary_small" msgid="6050633151263074260">"I vogël"</string> - <string name="screen_zoom_summary_default" msgid="1888865694033865408">"I parazgjedhur"</string> + <string name="screen_zoom_summary_default" msgid="1888865694033865408">"E parazgjedhur"</string> <string name="screen_zoom_summary_large" msgid="4706951482598978984">"I madh"</string> <string name="screen_zoom_summary_very_large" msgid="7317423942896999029">"Më i madh"</string> <string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"Më i madhi"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 45dbd365ba6d..e47969cef612 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Трајаће приближно до <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Батерија ће се можда испразнити до <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Преостало је мање од <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Преостало је мање од <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Преостало је више од <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Преостало је више од <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон ће се ускоро искључити"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Таблет ће се ускоро искључити"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Уређај ће се ускоро искључити"</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index efb4ddc75e03..c21e62490f0a 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Bör räcka ungefär till klockan <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Till kl. <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batteriet kan ta slut klockan <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Mindre än <xliff:g id="THRESHOLD">%1$s</xliff:g> återstår"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Mindre än <xliff:g id="THRESHOLD">%1$s</xliff:g> återstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Mer än <xliff:g id="TIME_REMAINING">%1$s</xliff:g> återstår (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Mer än <xliff:g id="TIME_REMAINING">%1$s</xliff:g> återstår"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefonen kanske stängs av snart"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Surfplattan kanske stängs av snart"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Enheten kanske stängs av snart"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index a0254cb0f3b1..66846fa25242 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Inapaswa kudumu hadi <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hadi <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Huenda chaji ikaisha kufikia <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Zimesalia chini ya <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Zimesalia chini ya <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Zimesalia zaidi ya <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Zimesalia zaidi ya <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Huenda simu ikazima hivi karibuni"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Huenda kompyuta yako kibao ikazima hivi karibuni"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Huenda kifaa kikazima hivi karibuni"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 8d251aca7bbb..4494d1a7ec68 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -251,7 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"வயர்லெஸ் காட்சிக்கான சான்றிதழ்"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"வைஃபை அதிவிவர நுழைவை இயக்கு"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"வைஃபை ஸ்கேனிங்கை வரம்பிடுதல்"</string> - <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"வைஃபை மேம்படுத்திய MAC ரேண்டம் ஆக்குதல்"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"வைஃபை மேம்பாட்டுடன் MAC ரேண்டம் ஆக்குதல்"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"மொபைல் டேட்டாவை எப்போதும் இயக்கத்திலேயே வை"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"பெயர்கள் இல்லாத புளூடூத் சாதனங்களைக் காட்டு"</string> @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"<xliff:g id="TIME">%1$s</xliff:g> வரை பயன்படுத்த முடியும்"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> வரை"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g>க்கு பேட்டரி காலியாகிவிடக்கூடும்"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g>க்கும் குறைவாகவே பயன்படுத்த முடியும்"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g>க்கும் குறைவாகவே பயன்படுத்த முடியும் (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>க்கும் மேல் பயன்படுத்த முடியும் (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>க்கும் மேல் பயன்படுத்த முடியும்"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"மொபைல் விரைவில் ஆஃப் ஆகக்கூடும்"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"டேப்லெட் விரைவில் ஆஃப் ஆகக்கூடும்"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"சாதனம் விரைவில் ஆஃப் ஆகக்கூடும்"</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index c51c042f0606..ff958ea1159a 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"దాదాపు <xliff:g id="TIME">%1$s</xliff:g> వరకు ఉండాలి"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> వరకు"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"బ్యాటరీ <xliff:g id="TIME">%1$s</xliff:g> సమయానికి ఖాళీ అవ్వచ్చు"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> కంటే తక్కువ సమయం మిగిలి ఉంది"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g> కంటే తక్కువ సమయం మిగిలి ఉంది (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> కంటే ఎక్కువ సమయం మిగిలి ఉంది (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> కంటే ఎక్కువ సమయం మిగిలి ఉంది"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"ఫోన్ త్వరలో షట్డౌన్ కావచ్చు"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"టాబ్లెట్ త్వరలో షట్డౌన్ కావచ్చు"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"పరికరం త్వరలో షట్డౌన్ కావచ్చు"</string> @@ -533,7 +537,7 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"వినియోగదారు"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"పరిమితం చేయబడిన ప్రొఫైల్"</string> <string name="user_add_user_title" msgid="5457079143694924885">"కొత్త వినియోగదారుని జోడించాలా?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"అదనపు వినియోగదారులను సృష్టించడం ద్వారా మీరు ఈ పరికరాన్ని ఇతరులతో షేర్ చేయవచ్చు. ప్రతి వినియోగదారుకు వారికంటూ ప్రత్యేక స్థలం ఉంటుంది, వారు ఆ స్థలాన్ని యాప్లు, వాల్పేపర్ మొదలైనవాటితో అనుకూలీకరించవచ్చు. వినియోగదారులు ప్రతి ఒక్కరిపై ప్రభావం చూపే Wi‑Fi వంటి పరికర సెట్టింగ్లను కూడా సర్దుబాటు చేయవచ్చు.\n\nమీరు కొత్త వినియోగదారును జోడించినప్పుడు, ఆ వ్యక్తి వారికంటూ స్వంత స్థలం సెట్ చేసుకోవాలి.\n\nఏ వినియోగదారు అయినా మిగిలిన అందరు వినియోగదారుల కోసం యాప్లను అప్డేట్ చేయవచ్చు. యాక్సెస్ సామర్ధ్యం సెట్టింగ్లు మరియు సేవలు కొత్త వినియోగదారుకి బదిలీ కాకపోవచ్చు."</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"అదనపు యూజర్లను సృష్టించడం ద్వారా మీరు ఈ దేవైజ్ను ఇతరులతో షేర్ చేయవచ్చు. ప్రతి యూజర్కు వారికంటూ ప్రత్యేక స్థలం ఉంటుంది, వారు ఆ స్థలాన్ని యాప్లు, వాల్పేపర్ మొదలైనవాటితో అనుకూలీకరించవచ్చు. యూజర్లు ప్రతి ఒక్కరిపై ప్రభావం చూపే Wi‑Fi వంటి పరికర సెట్టింగ్లను కూడా సర్దుబాటు చేయవచ్చు.\n\nమీరు కొత్త యూజర్ ను జోడించినప్పుడు, ఆ వ్యక్తి వారికంటూ స్వంత స్థలం సెట్ చేసుకోవాలి.\n\nఏ వినియోగదారు అయినా మిగిలిన అందరు యూజర్ల కోసం యాప్లను అప్డేట్ చేయవచ్చు. యాక్సెస్ సామర్ధ్యం సెట్టింగ్లు మరియు సేవలు కొత్త యూజర్కి బదిలీ కాకపోవచ్చు."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"మీరు కొత్త వినియోగదారుని జోడించినప్పుడు, ఆ వ్యక్తి తన స్థలాన్ని సెటప్ చేసుకోవాలి.\n\nఏ వినియోగదారు అయినా మిగతా అందరు వినియోగదారుల కోసం యాప్లను అప్డేట్ చేయగలరు."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"ఇప్పుడు వినియోగదారుని సెటప్ చేయాలా?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"పరికరాన్ని తీసుకోవడానికి వ్యక్తి అందుబాటులో ఉన్నారని నిర్ధారించుకొని, ఆపై వారికి నిల్వ స్థలాన్ని సెటప్ చేయండి"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 7ab86e8476e9..844a329b8df5 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"น่าจะใช้งานได้ถึงเวลาประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"จนถึง <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"แบตเตอรี่อาจหมดภายใน <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"เหลืออีกไม่ถึง <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"เหลือเวลาอีกไม่ถึง <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"เหลือเวลามากกว่า <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"เหลือเวลามากกว่า <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"โทรศัพท์อาจปิดเครื่องในไม่ช้า"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"แท็บเล็ตอาจปิดเครื่องในไม่ช้า"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"อุปกรณ์อาจปิดเครื่องในไม่ช้า"</string> @@ -487,7 +491,7 @@ <string name="ims_reg_title" msgid="8197592958123671062">"สถานะการลงทะเบียน IMS"</string> <string name="ims_reg_status_registered" msgid="884916398194885457">"ลงทะเบียนแล้ว"</string> <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"ไม่ได้ลงทะเบียน"</string> - <string name="status_unavailable" msgid="5279036186589861608">"ไม่ว่าง"</string> + <string name="status_unavailable" msgid="5279036186589861608">"ไม่มี"</string> <string name="wifi_status_mac_randomized" msgid="466382542497832189">"MAC เป็นแบบสุ่ม"</string> <plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139"> <item quantity="other">มีอุปกรณ์ที่เชื่อมต่อ %1$d เครื่อง</item> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index d3af3984789f..412be0f2b3aa 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Tatagal hanggang mga <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hanggang <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Posibleng maubos ang baterya sa loob ng <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Mahigit <xliff:g id="TIME_REMAINING">%1$s</xliff:g> pa ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Mahigit <xliff:g id="TIME_REMAINING">%1$s</xliff:g> pa ang natitira"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Baka mag-shut down na ang telepono"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Baka mag-shut down na ang tablet"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Baka mag-shut down na ang device"</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 039df1a0fd91..26f94bf1a2af 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Saat yaklaşık <xliff:g id="TIME">%1$s</xliff:g> olana kadar kullanılabilmelidir"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Şu saate kadar: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Pilin tahmini bitiş zamanı: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"En fazla <xliff:g id="THRESHOLD">%1$s</xliff:g> kaldı"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"En çok <xliff:g id="THRESHOLD">%1$s</xliff:g> kaldı (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"En az <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kaldı (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"En az <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kaldı"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon kısa süre içinde kapanabilir"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet kısa süre içinde kapanabilir"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Cihaz kısa süre içinde kapanabilir"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 60aa1a9abaaa..6f6b3fc84cf1 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Вистачить приблизно до <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"До <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Акумулятор може розрядитися до <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Залишилося менше ніж <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Залишилося менше ніж <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Залишилося понад <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Залишилося понад <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Телефон може невдовзі вимкнутися"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Планшет може невдовзі вимкнутися"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Пристрій може невдовзі вимкнутися"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index d1caa7119845..215cb4c83d58 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> gacha davom etadi"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> gacha"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batareya quvvati tugash vaqti: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g>dan kamroq vaqt qoldi"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g>dan kamroq vaqt qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>dan ko‘proq vaqt qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>dan ko‘proq vaqt qoldi"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Telefon tez orada oʻchib qolishi mumkin"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Planshet tez orada oʻchib qolishi mumkin"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Qurilma tez orada oʻchib qolishi mumkin"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 1d78d33a3830..e118ec0b72f1 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Pin sẽ hết vào khoảng <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Cho đến <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Điện thoại có thể hết pin vào <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Còn lại không đến <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Còn lại không đến <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Còn lại hơn <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Còn lại hơn <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Điện thoại có thể sắp tắt"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Máy tính bảng có thể sắp tắt"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Thiết bị có thể sắp tắt"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 5c65dff7b282..9edcff2c6e5e 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -78,7 +78,7 @@ <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"已连接(无手机或媒体信号),电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"使用中,电池电量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"已启用,左:目前电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>;右:目前电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> - <string name="bluetooth_battery_level" msgid="2893696778200201555">"电池电量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> 的电量"</string> <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"左:目前电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>;右:目前电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"使用中"</string> <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"媒体音频"</string> @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"直到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"电池电量可能在<xliff:g id="TIME">%1$s</xliff:g> 前耗尽"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"电量剩余使用时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"电量剩余使用时间超过 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"电量剩余使用时间超过 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"手机可能即将关机"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"平板电脑可能即将关机"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"设备可能即将关机"</string> @@ -498,7 +502,7 @@ <string name="cancel" msgid="5665114069455378395">"取消"</string> <string name="okay" msgid="949938843324579502">"确定"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"开启"</string> - <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"开启“勿扰”模式"</string> + <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"开启勿扰模式"</string> <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"永不"</string> <string name="zen_interruption_level_priority" msgid="5392140786447823299">"仅限优先事项"</string> <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 3720581e837d..b6ad4fdf7b46 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"電量大約可用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"還可用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"電池電量可能將於<xliff:g id="TIME">%1$s</xliff:g>耗盡"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"剩餘電量時間少於 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"還有少於 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"還有超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"還有超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"手機可能即將關閉"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"平板電腦可能即將關機"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"裝置可能即將關機"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 9337b59c258e..04b5cb6ba2c9 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"預估電力大約可使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"還能持續使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"電池電力可能於<xliff:g id="TIME">%1$s</xliff:g> 前耗盡"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"電池可用時間不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"電池可用時間不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"電池可用時間超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"電池可用時間超過 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"手機可能即將關機"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"平板電腦可能即將關機"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"裝置可能即將關機"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index a552446e6acf..7e849189f62e 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -436,10 +436,14 @@ <string name="power_discharge_by_only" msgid="92545648425937000">"Kumele ihlale cishe kube ngu-<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Kuze kube ngu-<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Ibhethri lingaphela ngo-<xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Kusele okungaphansi kunokungu-<xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> - <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"Ngaphansi kuka-<xliff:g id="THRESHOLD">%1$s</xliff:g> osele (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"Ngaphezu kuka-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> osele (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_only_more_than_subtext" msgid="3274496164769110480">"Ngaphezulu kokungu-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> okusele"</string> + <!-- no translation found for power_remaining_less_than_duration_only (8956656616031395152) --> + <skip /> + <!-- no translation found for power_remaining_less_than_duration (318215464914990578) --> + <skip /> + <!-- no translation found for power_remaining_more_than_subtext (446388082266121894) --> + <skip /> + <!-- no translation found for power_remaining_only_more_than_subtext (4873750633368888062) --> + <skip /> <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Ifoni ingacisha maduze"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Ithebulethi ingacisha maduze"</string> <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Idivayisi ingacisha maduze"</string> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index 1007d8379b8e..7baaf494771b 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -1080,14 +1080,14 @@ <string name="power_suggestion_battery_run_out">Battery may run out by <xliff:g id="time" example="12 PM">%1$s</xliff:g></string> <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount --> - <string name="power_remaining_less_than_duration_only">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining</string> + <string name="power_remaining_less_than_duration_only">Less than <xliff:g id="threshold">%1$s</xliff:g> left</string> <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount with the percentage --> - <string name="power_remaining_less_than_duration">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining (<xliff:g id="level">%2$s</xliff:g>)</string> + <string name="power_remaining_less_than_duration">Less than <xliff:g id="threshold">%1$s</xliff:g> left (<xliff:g id="level">%2$s</xliff:g>)</string> <!-- Used to let users know that they have more than some amount of battery life remaining with percentage. ex: 75% - more than 1 day remaining [CHAR LIMIT = 80] --> - <string name="power_remaining_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> remaining (<xliff:g id="level">%2$s</xliff:g>)</string> + <string name="power_remaining_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> left (<xliff:g id="level">%2$s</xliff:g>)</string> <!-- Used to let users know that they have more than some amount of battery life remaining. ex: more than 1 day remaining [CHAR LIMIT = 40] --> - <string name="power_remaining_only_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> remaining</string> + <string name="power_remaining_only_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> left</string> <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device --> <string name="power_remaining_duration_only_shutdown_imminent" product="default">Phone may shut down soon</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java index deccde593315..a210e90a3cfc 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java @@ -358,49 +358,45 @@ public class EnableZenModeDialog { } }); - // minus button - final ImageView button1 = (ImageView) row.findViewById(android.R.id.button1); - button1.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onClickTimeButton(row, tag, false /*down*/, rowId); - tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE); - } - }); - - // plus button - final ImageView button2 = (ImageView) row.findViewById(android.R.id.button2); - button2.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onClickTimeButton(row, tag, true /*up*/, rowId); - tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE); - } - }); - final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId); + final ImageView minusButton = (ImageView) row.findViewById(android.R.id.button1); + final ImageView plusButton = (ImageView) row.findViewById(android.R.id.button2); if (rowId == COUNTDOWN_CONDITION_INDEX && time > 0) { - button1.setVisibility(View.VISIBLE); - button2.setVisibility(View.VISIBLE); + minusButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onClickTimeButton(row, tag, false /*down*/, rowId); + tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE); + } + }); + + plusButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onClickTimeButton(row, tag, true /*up*/, rowId); + tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE); + } + }); if (mBucketIndex > -1) { - button1.setEnabled(mBucketIndex > 0); - button2.setEnabled(mBucketIndex < MINUTE_BUCKETS.length - 1); + minusButton.setEnabled(mBucketIndex > 0); + plusButton.setEnabled(mBucketIndex < MINUTE_BUCKETS.length - 1); } else { final long span = time - System.currentTimeMillis(); - button1.setEnabled(span > MIN_BUCKET_MINUTES * MINUTES_MS); + minusButton.setEnabled(span > MIN_BUCKET_MINUTES * MINUTES_MS); final Condition maxCondition = ZenModeConfig.toTimeCondition(mContext, MAX_BUCKET_MINUTES, ActivityManager.getCurrentUser()); - button2.setEnabled(!Objects.equals(condition.summary, maxCondition.summary)); + plusButton.setEnabled(!Objects.equals(condition.summary, maxCondition.summary)); } - button1.setAlpha(button1.isEnabled() ? 1f : .5f); - button2.setAlpha(button2.isEnabled() ? 1f : .5f); + minusButton.setAlpha(minusButton.isEnabled() ? 1f : .5f); + plusButton.setAlpha(plusButton.isEnabled() ? 1f : .5f); } else { - if (button1 != null) { - ((ViewGroup) row).removeView(button1); + if (minusButton != null) { + ((ViewGroup) row).removeView(minusButton); } - if (button2 != null) { - ((ViewGroup) row).removeView(button2); + + if (plusButton != null) { + ((ViewGroup) row).removeView(plusButton); } } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java index 342d127abd03..4b779ac4a7f5 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java @@ -137,9 +137,9 @@ public class PowerUtilTest { true /* basedOnUsage */); // shortened string should not have percentage - assertThat(info).isEqualTo("Less than 15 min remaining"); + assertThat(info).isEqualTo("Less than 15 min left"); // Add percentage to string when provided - assertThat(info2).isEqualTo("Less than 15 min remaining (10%)"); + assertThat(info2).isEqualTo("Less than 15 min left (10%)"); } @Test @@ -171,9 +171,9 @@ public class PowerUtilTest { true /* basedOnUsage */); // shortened string should not have percentage - assertThat(info).isEqualTo("More than 2 days remaining"); + assertThat(info).isEqualTo("More than 2 days left"); // Add percentage to string when provided - assertThat(info2).isEqualTo("More than 2 days remaining (10%)"); + assertThat(info2).isEqualTo("More than 2 days left (10%)"); } @Test @@ -181,7 +181,7 @@ public class PowerUtilTest { String info = PowerUtil.getBatteryTipStringFormatted(mContext, THREE_DAYS_MILLIS); - assertThat(info).isEqualTo("More than 3 days remaining"); + assertThat(info).isEqualTo("More than 3 days left"); } @Test diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index 736e995451cd..c04a1ba689b9 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -97,6 +97,7 @@ public class SecureSettings { Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, Settings.Secure.QS_TILES, Settings.Secure.CONTROLS_ENABLED, + Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT, Settings.Secure.DOZE_ENABLED, Settings.Secure.DOZE_ALWAYS_ON, Settings.Secure.DOZE_PICK_UP_GESTURE, diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index b413e8e9dda2..76746e5488b6 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -142,6 +142,7 @@ public class SecureSettingsValidators { VALIDATORS.put(Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.QS_TILES, TILE_LIST_VALIDATOR); VALIDATORS.put(Secure.CONTROLS_ENABLED, BOOLEAN_VALIDATOR); + VALIDATORS.put(Secure.POWER_MENU_LOCKED_SHOW_CONTENT, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.DOZE_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.DOZE_ALWAYS_ON, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.DOZE_PICK_UP_GESTURE, BOOLEAN_VALIDATOR); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index 8a7b9134a5d9..a5dce6da348f 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -2278,6 +2278,12 @@ class SettingsProtoDumpUtil { SecureSettingsProto.ParentalControl.REDIRECT_URL); p.end(parentalControlToken); + final long powerMenuPrivacyToken = p.start(SecureSettingsProto.POWER_MENU_PRIVACY); + dumpSetting(s, p, + Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT, + SecureSettingsProto.PowerMenuPrivacy.SHOW); + p.end(powerMenuPrivacyToken); + final long printServiceToken = p.start(SecureSettingsProto.PRINT_SERVICE); dumpSetting(s, p, Settings.Secure.PRINT_SERVICE_SEARCH_URI, diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index d3d04e5a31d0..74eee6300b2a 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -3437,7 +3437,7 @@ public class SettingsProvider extends ContentProvider { } private final class UpgradeController { - private static final int SETTINGS_VERSION = 189; + private static final int SETTINGS_VERSION = 190; private final int mUserId; @@ -4777,6 +4777,28 @@ public class SettingsProvider extends ContentProvider { currentVersion = 189; } + if (currentVersion == 189) { + final SettingsState secureSettings = getSecureSettingsLocked(userId); + final Setting showNotifications = secureSettings.getSettingLocked( + Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS); + final Setting allowPrivateNotifications = secureSettings.getSettingLocked( + Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS); + if ("1".equals(showNotifications.getValue()) + && "1".equals(allowPrivateNotifications.getValue())) { + secureSettings.insertSettingLocked( + Secure.POWER_MENU_LOCKED_SHOW_CONTENT, + "1", null /* tag */, false /* makeDefault */, + SettingsState.SYSTEM_PACKAGE_NAME); + } else if ("0".equals(showNotifications.getValue()) + || "0".equals(allowPrivateNotifications.getValue())) { + secureSettings.insertSettingLocked( + Secure.POWER_MENU_LOCKED_SHOW_CONTENT, + "0", null /* tag */, false /* makeDefault */, + SettingsState.SYSTEM_PACKAGE_NAME); + } + currentVersion = 190; + } + // vXXX: Add new settings above this point. if (currentVersion != newVersion) { diff --git a/packages/SystemUI/res/drawable/screenshot_cancel.xml b/packages/SystemUI/res/drawable/screenshot_cancel.xml index be3c5983bb2e..f0dfd21a830d 100644 --- a/packages/SystemUI/res/drawable/screenshot_cancel.xml +++ b/packages/SystemUI/res/drawable/screenshot_cancel.xml @@ -20,9 +20,9 @@ android:viewportWidth="48.0" android:viewportHeight="48.0"> <path - android:pathData="M24,24m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0" - android:fillColor="@android:color/white"/> + android:fillColor="@color/global_screenshot_dismiss_background" + android:pathData="M24,24m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"/> <path - android:fillColor="@color/GM2_grey_500" + android:fillColor="@color/global_screenshot_dismiss_foreground" android:pathData="M31,18.41L29.59,17 24,22.59 18.41,17 17,18.41 22.59,24 17,29.59 18.41,31 24,25.41 29.59,31 31,29.59 25.41,24z"/> </vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/controls_detail_dialog.xml b/packages/SystemUI/res/layout/controls_detail_dialog.xml index 34b603f4bc3d..d1ce10e5745f 100644 --- a/packages/SystemUI/res/layout/controls_detail_dialog.xml +++ b/packages/SystemUI/res/layout/controls_detail_dialog.xml @@ -50,41 +50,15 @@ android:padding="12dp" /> </LinearLayout> - <LinearLayout + <FrameLayout + android:id="@+id/controls_activity_view" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="0dp" + android:layout_weight="1" android:paddingTop="@dimen/controls_activity_view_top_padding" android:paddingLeft="@dimen/controls_activity_view_side_padding" android:paddingRight="@dimen/controls_activity_view_side_padding" android:background="@drawable/rounded_bg_top" - android:orientation="vertical"> - <TextView - android:id="@+id/title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.ControlDialog" - android:clickable="false" - android:focusable="false" - android:maxLines="1" - android:ellipsize="end" /> - <TextView - android:id="@+id/subtitle" - android:layout_marginTop="6dp" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.ControlDialog" - android:clickable="false" - android:focusable="false" - android:maxLines="1" - android:ellipsize="end" /> - - <FrameLayout - android:id="@+id/controls_activity_view" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginTop="10dp" - android:layout_weight="1" /> - - </LinearLayout> + android:orientation="vertical" /> </LinearLayout> diff --git a/packages/SystemUI/res/layout/controls_management.xml b/packages/SystemUI/res/layout/controls_management.xml index 6da96d10c253..835e54e9e433 100644 --- a/packages/SystemUI/res/layout/controls_management.xml +++ b/packages/SystemUI/res/layout/controls_management.xml @@ -26,41 +26,15 @@ android:paddingStart="@dimen/controls_management_side_padding" android:paddingEnd="@dimen/controls_management_side_padding" > - <LinearLayout - android:orientation="horizontal" + + <TextView + android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:focusable="false" - android:clickable="false" - android:gravity="center_vertical"> - - <FrameLayout - android:id="@+id/icon_frame" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:gravity="start|center_vertical" - android:minWidth="56dp" - android:visibility="gone" - android:paddingTop="@dimen/controls_app_icon_frame_top_padding" - android:paddingBottom="@dimen/controls_app_icon_frame_bottom_padding" - android:paddingEnd="@dimen/controls_app_icon_frame_side_padding" - android:paddingStart="@dimen/controls_app_icon_frame_side_padding" > - - <ImageView - android:id="@android:id/icon" - android:layout_width="@dimen/controls_app_icon_size" - android:layout_height="@dimen/controls_app_icon_size" /> - </FrameLayout> - - <TextView - android:id="@+id/title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textAppearance="?android:attr/textAppearanceLarge" - android:textSize="@dimen/controls_title_size" - android:textAlignment="center" /> + android:textAppearance="?android:attr/textAppearanceLarge" + android:textSize="@dimen/controls_title_size" + android:textAlignment="center" /> - </LinearLayout> <TextView diff --git a/packages/SystemUI/res/layout/global_actions_grid_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_v2.xml index 1c4ec64e9620..66f57fd6f37c 100644 --- a/packages/SystemUI/res/layout/global_actions_grid_v2.xml +++ b/packages/SystemUI/res/layout/global_actions_grid_v2.xml @@ -14,7 +14,6 @@ android:theme="@style/qs_theme" android:clipChildren="false" android:clipToPadding="false" - android:layout_marginTop="@dimen/global_actions_top_margin" android:layout_marginStart="@dimen/global_actions_side_margin" > <LinearLayout @@ -51,6 +50,7 @@ android:paddingBottom="@dimen/global_actions_grid_container_shadow_offset" android:layout_marginBottom="@dimen/global_actions_grid_container_negative_shadow_offset" android:orientation="vertical" + android:scrollbars="none" > <LinearLayout android:id="@+id/global_actions_grid_root" diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml index d506e7e8e700..db109fe8a541 100644 --- a/packages/SystemUI/res/layout/global_screenshot.xml +++ b/packages/SystemUI/res/layout/global_screenshot.xml @@ -68,6 +68,7 @@ android:visibility="gone" android:contentDescription="@string/screenshot_dismiss_ui_description"> <ImageView + android:id="@+id/global_screenshot_dismiss_image" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="@dimen/screenshot_dismiss_button_margin" diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 8342ccd55cfb..1008d2bb24fd 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Beheer borrels enige tyd"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tik op Bestuur om borrels vanaf hierdie program af te skakel"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Het dit"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Stelselnavigasie is opgedateer. Gaan na Instellings toe om veranderinge te maak."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gaan na Instellings toe om stelselnavigasie op te dateer"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Bystandmodus"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Wys boaan gespreksafdeling"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Wys profielprent op slotskerm"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Verskyn as \'n swewende borrel bo-oor programme"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Onderbreek Moenie Steur Nie"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Het dit"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Vergrotingoorleggervenster"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Vergrotingvenster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Vergrotingvensterkontroles"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index aacd994675a7..7e2ec10fd90d 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"በማንኛውም ጊዜ አረፋዎችን ይቆጣጠሩ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"የዚህ መተግበሪያ አረፋዎችን ለማጥፋት አቀናብርን መታ ያድርጉ"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ገባኝ"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"የስርዓት ዳሰሳ ተዘምኗል። ለውጦችን ለማድረግ ወደ ቅንብሮች ይሂዱ።"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"የስርዓት ዳሰሳን ለማዘመን ወደ ቅንብሮች ይሂዱ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ተጠባባቂ"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"በውይይት ክፍል አናት ላይ አአሳይ"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"የመገለጫ ስዕልን በማያ ገጽ ቁልፍ ላይ አሳይ"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"በመተግበሪያዎች ላይ እንደ ተንሳፋፊ አረፋ ሆኖ ይታያሉ"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"አትረብሽን አቋርጥ"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"ገባኝ"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"የማጉያ ንብርብር መስኮት"</string> <string name="magnification_window_title" msgid="4863914360847258333">"የማጉያ መስኮት"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"የማጉያ መስኮት መቆጣጠሪያዎች"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 2410ca63b681..0ada0dc0f9c8 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -87,8 +87,7 @@ <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"يتعذر حفظ لقطة الشاشة لأن مساحة التخزين المتاحة محدودة."</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"يحظر التطبيق أو تحظر مؤسستك التقاط لقطات شاشة"</string> <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"إغلاق لقطة الشاشة"</string> - <!-- no translation found for screenshot_preview_description (7606510140714080474) --> - <skip /> + <string name="screenshot_preview_description" msgid="7606510140714080474">"معاينة لقطة الشاشة"</string> <string name="screenrecord_name" msgid="2596401223859996572">"مسجّل الشاشة"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"إشعار مستمر لجلسة تسجيل شاشة"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"هل تريد بدء التسجيل؟"</string> @@ -1020,25 +1019,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"التحكّم في فقاعات المحادثات في أي وقت"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"انقر على \"إدارة\" لإيقاف فقاعات المحادثات من هذا التطبيق."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"حسنًا"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"تم تحديث التنقل داخل النظام. لإجراء التغييرات، يُرجى الانتقال إلى \"الإعدادات\"."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"الانتقال إلى \"الإعدادات\" لتعديل التنقل داخل النظام"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"وضع الاستعداد"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"تظهر في أعلى قسم المحادثات"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"إظهار صورة الملف الشخصي على شاشة القفل"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"تظهر كفقاعة عائمة فوق التطبيقات"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"مقاطعة ميزة \"عدم الإزعاج\""</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"حسنًا"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"نافذة تراكب التكبير"</string> <string name="magnification_window_title" msgid="4863914360847258333">"نافذة التكبير"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"عناصر التحكم في نافذة التكبير"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"عناصر التحكم في الأجهزة"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"أدوات التحكم بالجهاز"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"إضافة عناصر تحكّم لأجهزتك المتصلة"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"إعداد عناصر التحكم في الأجهزة"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"إعداد أدوات التحكم بالجهاز"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"اضغط مع الاستمرار على زر التشغيل للوصول إلى عناصر التحكّم"</string> <string name="controls_providers_title" msgid="6879775889857085056">"اختيار تطبيق لإضافة عناصر التحكّم"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1055,7 +1051,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"تمت إزالة كل عناصر التحكّم."</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"تعذّر تحميل قائمة كل عناصر التحكّم."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"غير ذلك"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"إضافة إلى عناصر التحكم في الأجهزة"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"إضافة إلى أدوات التحكم بالجهاز"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"إضافة إلى الإعدادات المفضّلة"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"اقترح تطبيق <xliff:g id="APP">%s</xliff:g> إضافة عنصر التحكّم هذا إلى الإعدادات المفضّلة."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"تم تعديل عناصر التحكّم."</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 9ea949e08976..99cc25d63834 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -707,8 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"বাবল"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"কোনো ধ্বনি অথবা কম্পন অবিহনে আপোনাক মনোযোগ দিয়াত সহায় কৰে।"</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"ধ্বনি অথবা কম্পনৰ জৰিয়তে আপোনাৰ মনোযোগ আকৰ্ষণ কৰে।"</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"ধ্বনি অথবা কম্পনৰ জৰিয়তে আপোনাৰ মনোযোগ আকৰ্ষণ কৰে। <xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাৰ্তালাপ ডিফ’ল্ট হিচাপে বাবল হয়।"</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"উপঙি থকা এটা শ্বৰ্টকাটৰ জৰিয়তে এই সমলখিনিৰ প্ৰতি আপোনাক মনোযোগী কৰি ৰাখে।"</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"বাৰ্তালাপ শাখাটোৰ শীৰ্ষত দেখুৱায় আৰু এটা বাবল হিচাপে প্ৰদর্শন হয়।"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ছেটিংসমূহ"</string> @@ -1000,6 +999,8 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"যিকোনো সময়তে bubbles নিয়ন্ত্ৰণ কৰক"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"এই এপ্টোৰ পৰা bubbles অফ কৰিবলৈ পৰিচালনা কৰকত টিপক"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"বুজি পালোঁ"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰা হ’ল। সলনি কৰিবলৈ ছেটিংসমূহ-লৈ যাওক।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰিবলৈ ছেটিংসমূহ-লৈ যাওক"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ষ্টেণ্ডবাই"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 8e14f9c26b51..bbb51e140252 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -945,7 +945,7 @@ <string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> işləyir"</string> <string name="instant_apps_message" msgid="6112428971833011754">"Quraşdırılmadan açılan tətbiq."</string> <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Quraşdırılmadan açılan tətbiq. Ətraflı məlumat üçün klikləyin."</string> - <string name="app_info" msgid="5153758994129963243">"Tətbiq haqqında"</string> + <string name="app_info" msgid="5153758994129963243">"Tətbiq infosu"</string> <string name="go_to_web" msgid="636673528981366511">"Brauzerə daxil edin"</string> <string name="mobile_data" msgid="4564407557775397216">"Mobil data"</string> <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string> @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Yumrucuqları istənilən vaxt idarə edin"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bu tətbiqdə yumrucuqları deaktiv etmək üçün \"İdarə edin\" seçiminə toxunun"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Anladım"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistem naviqasiyası yeniləndi. Dəyişiklik etmək üçün Ayarlara daxil olun."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistem naviqasiyasını yeniləmək üçün Ayarlara keçin"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gözləmə rejimi"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Söhbət bölməsinin yuxarısında göstərilir"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Kilid ekranında profil şəkli göstərilir"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Tətbiqlərin üzərində üzən qabarcıq kimi görünəcək"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Narahat Etməyin rejimi bölünsün"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Anladım"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Böyütmə Üst-üstə Düşən Pəncərəsi"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Böyütmə Pəncərəsi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Böyütmə Pəncərəsi Kontrolları"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Cihaz nizamlayıcıları"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Cihaz idarəetmələri"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Qoşulmuş cihazlarınız üçün nizamlayıcılar əlavə edin"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Cihaz nizamlayıcılarını ayarlayın"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Cihaz idarəetmələrini ayarlayın"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Nizamlayıcılara giriş üçün Yandırıb-söndürmə düyməsini basıb saxlayın"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Nizamlayıcıları əlavə etmək üçün tətbiq seçin"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Bütün nizamlayıcılar silindi"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Bütün nizamlayıcıların siyahısı yüklənmədi."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Digər"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Cihaz nizamlayıcılarına əlavə edin"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Cihaz idarəetmələrinə əlavə edin"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Sevimlilərə əlavə edin"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> sevimlilərə əlavə etmək üçün bu nizamlayıcını təklif edib."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Nizamlayıcılar güncəlləndi"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index da7f61bf9f5e..cef3cceb9cdc 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -1004,19 +1004,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrolišite oblačiće u bilo kom trenutku"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dodirnite Upravljajte da biste isključili oblačiće iz ove aplikacije"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Važi"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigacija sistema je ažurirana. Da biste uneli izmene, idite u Podešavanja."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Podešavanja da biste ažurirali navigaciju sistema"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravnosti"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazuju se u vrhu odeljka za konverzacije"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazuju sliku profila na zaključanom ekranu"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Prikazuju se plutajući oblačići preko aplikacija"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ometaju podešavanje Ne uznemiravaj"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Važi"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Preklopni prozor za uvećanje"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za uvećanje"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za uvećanje"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index c19fde3a429b..a4aea02f98aa 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -1009,19 +1009,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Кіруйце ўсплывальнымі апавяшчэннямі ў любы час"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Каб выключыць усплывальныя апавяшчэнні з гэтай праграмы, націсніце \"Кіраваць\""</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Зразумела"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацыя ў сістэме абноўлена. Каб унесці змяненні, перайдзіце ў Налады."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перайдзіце ў Налады, каб абнавіць параметры навігацыі ў сістэме"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Рэжым чакання"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Паказваюцца ўверсе раздзела размоў"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Паказваюць выяву профілю на экране блакіроўкі"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Паказваюцца як рухомыя апавяшчэнні паверх праграм"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Не распаўсюджваюцца на рэжым \"Не турбаваць\""</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Зразумела"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Акно-накладка з павелічэннем"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Акно павелічэння"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Налады акна павелічэння"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 5c21653ec6fd..9a505cbb8d92 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Управление на балончетата по всяко време"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Докоснете „Управление“, за да изключите балончетата от това приложение"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Разбрах"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Режимът за навигиране в системата е актуализиран. За да извършите промени, отворете настройките."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Отворете настройките, за да актуализирате режима за навигиране в системата"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим на готовност"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Показване върху секцията с разговори"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Показване на снимката на потр. профил на закл. екран"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Показва се като плаващо балонче върху приложенията"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Прекъсване на режима „Не безпокойте“"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Разбрах"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Прозорец с наслагване за ниво на мащаба"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Прозорец за ниво на мащаба"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Контроли за прозореца за ниво на мащаба"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 6f12900f71fe..ca0296415510 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -707,8 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"বাবল"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"সাউন্ড বা ভাইব্রেশন ছাড়া ফোকাস করতে আপনাকে সাহায্য করে।"</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"সাউন্ড বা ভাইব্রেশনের সাহায্যে দৃষ্টি আকর্ষণ করে।"</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"সাউন্ড বা ভাইব্রেশনের সাহায্যে দৃষ্টি আকর্ষণ করে। ডিফল্টভাবে <xliff:g id="APP_NAME">%1$s</xliff:g> বাবল থেকে কথোপকথন।"</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ফ্লোটিং শর্টকাট ব্যবহার করে এই কন্টেন্টে আপনার দৃষ্টি আকর্ষণ করে রাখে।"</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"কথোপকথন বিভাগের উপরে বাবল হিসেবে দেখা যায়।"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"সেটিংস"</string> @@ -1000,6 +999,8 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"যেকোনও সময় বাবল নিয়ন্ত্রণ করুন"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"এই অ্যাপ থেকে বাবল বন্ধ করতে ম্যানেজ করুন বিকল্প ট্যাপ করুন"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"বুঝেছি"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"সিস্টেম নেভিগেশন আপডেট হয়েছে। পরিবর্তন করার জন্য সেটিংসে যান।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"সিস্টেম নেভিগেশন আপডেট করতে সেটিংসে যান"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"স্ট্যান্ডবাই"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 29b435f5d530..4692c0bd4400 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -1006,19 +1006,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljajte oblačićima u svakom momentu"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dodirnite Upravljaj da isključite oblačiće iz ove aplikacije"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Razumijem"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Postavke za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigiranje sistemom je ažurirano. Da izvršite promjene, idite u Postavke."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Postavke da ažurirate navigiranje sistemom"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazuje se iznad odjeljka za razgovor"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazuje sliku profila na zaključanom ekranu"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Izgleda kao plutajući oblačić iznad aplikacija"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Prekida način rada Ne ometaj"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Razumijem"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Preklopni prozor za uvećavanje"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za uvećavanje"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za uvećavanje"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 3a859cbf6cb3..3697151f900a 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -88,7 +88,7 @@ <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'aplicació o la teva organització no permeten fer captures de pantalla"</string> <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ignora la captura de pantalla"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"Previsualització de la captura de pantalla"</string> - <string name="screenrecord_name" msgid="2596401223859996572">"Gravadora de pantalla"</string> + <string name="screenrecord_name" msgid="2596401223859996572">"Gravació de pantalla"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificació en curs d\'una sessió de gravació de la pantalla"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"Vols iniciar la gravació?"</string> <string name="screenrecord_description" msgid="1123231719680353736">"Quan graves contingut, el sistema Android pot capturar qualsevol informació sensible que es mostri a la pantalla o que es reprodueixi al dispositiu. Això inclou les contrasenyes, la informació de pagament, les fotos, els missatges i l\'àudio."</string> @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla les bombolles en qualsevol moment"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toca Gestiona per desactivar les bombolles d\'aquesta aplicació"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entesos"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"S\'ha actualitzat el sistema de navegació. Per fer canvis, ves a Configuració."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ves a Configuració per actualitzar el sistema de navegació"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Mostra a la part superior de la secció de converses"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostra la foto de perfil a la pantalla de bloqueig"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Es mostra com a bombolla flotant en primer pla"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interromp el mode No molestis"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Entesos"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Finestra superposada d\'ampliació"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Finestra d\'ampliació"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Finestra de controls d\'ampliació"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Controls del dispositiu"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Controls de dispositius"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Afegeix controls per als teus dispositius connectats"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configura els controls del dispositiu"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configura els controls de dispositius"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Mantén el botó d\'engegada premut per accedir als teus controls"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Selecciona l\'aplicació per afegir controls"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"S\'han suprimit tots els controls"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"No s\'ha pogut carregar la llista completa de controls."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Altres"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Afegeix als controls del dispositiu"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Afegeix als controls de dispositius"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Afegeix als preferits"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> ha suggerit aquest control perquè l\'afegeixis als preferits."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"S\'han actualitzat els controls"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index a09e9dbac146..15fff7389791 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -1009,25 +1009,21 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Nastavení bublin můžete kdykoli upravit"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bubliny pro tuto aplikaci můžete vypnout klepnutím na Spravovat"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Rozumím"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> – nastavení"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systémová navigace byla aktualizována. Chcete-li provést změny, přejděte do Nastavení."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Přejděte do Nastavení a aktualizujte systémovou navigaci"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostní režim"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Zobrazovat v horní části sekce konverzace"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Zobrazovat profilovou fotku na zámku obrazovky"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Zobrazuje se jako plovoucí bublina nad aplikacemi"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Přerušit režim Nerušit"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Rozumím"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Překryvné zvětšovací okno"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Zvětšovací okno"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ovládací prvky zvětšovacího okna"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Ovládací prvky zařízení"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Ovládání zařízení"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Přidejte ovládací prvky pro připojená zařízení"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavení ovládacích prvků zařízení"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavení ovládání zařízení"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Podržením vypínače zobrazíte ovládací prvky"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Vyberte aplikaci, pro kterou chcete přidat ovládací prvky"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1042,7 +1038,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Všechny ovládací prvky byly odstraněny"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Načtení seznamu všech ovládacích prvků se nezdařilo."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Jiné"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Přidání ovládacích prvků zařízení"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Přidání ovládání zařízení"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Přidat k oblíbeným"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"Aplikace <xliff:g id="APP">%s</xliff:g> navrhuje přidat tento ovládací prvek do oblíbených."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Ovládací prvky aktualizovány"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index e134c8e5f938..f996cb9fe152 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Styr bobler når som helst"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tryk på Administrer for at deaktivere bobler fra denne app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigationen blev opdateret. Gå til Indstillinger for at foretage ændringer."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Indstillinger for at opdatere systemnavigationen"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Vis i toppen af samtalesektionen"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Vis profilbillede på låseskærm"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Vis som en boble oven på apps"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Afbryd Forstyr ikke"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Vindue med overlejret forstørrelse"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Vindue med forstørrelse"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Vindue med forstørrelsesstyring"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Styring af enheder"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Enhedsstyring"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Tilføj betjeningselementer på dine tilsluttede enheder"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurer styring af enheder"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurer enhedsstyring"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Hold afbryderknappen nede for at få adgang til dine betjeningselementer"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Vælg en app for at tilføje betjeningselementer"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Alle styringselementerne blev fjernet"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Listen over styringselementer kunne ikke indlæses."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Andre"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Føj til styring af enheder"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Føj til enhedsstyring"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Føj til favoritter"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> har foreslået, at du føjer denne funktion til dine favoritter."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Betjeningselementerne er opdateret"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index de892696d11d..31837eded54a 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -707,8 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"Bubble"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"Benachrichtigungen werden ohne Ton oder Vibration angekündigt, um deine Konzentration nicht zu stören."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"Benachrichtigungen werden mit einem Ton oder einer Vibration angekündigt."</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Benachrichtigungen werden mit einem Ton oder einer Vibration angekündigt. Unterhaltungen von <xliff:g id="APP_NAME">%1$s</xliff:g> werden standardmäßig als Bubble angezeigt."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Du wirst mit einer unverankerten Verknüpfung darauf aufmerksam gemacht."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Wird oben im Bereich für Unterhaltungen als Bubble angezeigt."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Einstellungen"</string> @@ -1000,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Bubble-Einstellungen festlegen"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tippe auf \"Verwalten\", um Bubbles für diese App zu deaktivieren"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemsteuerungseinstellungen wurden angepasst. Änderungen kannst du in den Einstellungen vornehmen."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gehe zu den Einstellungen, um die Systemsteuerung anzupassen"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Oben im Bereich für Unterhaltungen anzeigen"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Profilbild auf Sperrbildschirm anzeigen"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Unverankertes Infofeld über anderen Apps"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\"Bitte nicht stören\" unterbrechen"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Overlay-Vergrößerungsfenster"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Vergrößerungsfenster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Einstellungen für Vergrößerungsfenster"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index cc3ee45cef27..b3142e9b9616 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ελέγξτε τα συννεφάκια ανά πάσα στιγμή."</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Πατήστε Διαχείριση για να απενεργοποιήσετε τα συννεφάκια από αυτήν την εφαρμογή."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Το κατάλαβα."</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Η πλοήγηση συστήματος ενημερώθηκε. Για να κάνετε αλλαγές, μεταβείτε στις Ρυθμίσεις."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Μεταβείτε στις Ρυθμίσεις για να ενημερώσετε την πλοήγηση συστήματος"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Κατάσταση αναμονής"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Εμφάνιση στο επάνω μέρος της ενότητας συνομιλιών"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Εμφάνιση εικόνας προφίλ στην οθόνη κλειδώματος"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Κινούμενο συννεφάκι στο επάνω μέρος των εφαρμογών"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Διακοπή λειτουργίας Μην ενοχλείτε"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Το κατάλαβα"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Παράθυρο επικάλυψης μεγέθυνσης"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Παράθυρο μεγέθυνσης"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Στοιχεία ελέγχου παραθύρου μεγέθυνσης"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 69109a7c28d4..b4c380b4794a 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -999,6 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Control bubbles at any time"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tap Manage to turn off bubbles from this app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index fdcad121543a..c719ea022478 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -999,6 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Control bubbles at any time"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tap Manage to turn off bubbles from this app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 69109a7c28d4..b4c380b4794a 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -999,6 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Control bubbles at any time"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tap Manage to turn off bubbles from this app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 69109a7c28d4..b4c380b4794a 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -999,6 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Control bubbles at any time"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tap Manage to turn off bubbles from this app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 2ad380993c46..2e5f1e726879 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -999,6 +999,7 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Control bubbles anytime"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tap Manage to turn off bubbles from this app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Got it"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"System navigation updated. To make changes, go to Settings."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Go to Settings to update system navigation"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index d18b88c66764..879fc35811a3 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas en todo momento"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Presiona Administrar para desactivar las burbujas de esta app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se actualizó el sistema de navegación. Para hacer cambios, ve a Configuración."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Configuración para actualizar la navegación del sistema"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Se muestran en la parte superior de conversaciones"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Muestran una foto de perfil en pantalla de bloqueo"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecen como burbujas flotantes encima de apps"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Suspender No interrumpir"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Entendido"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Ventana superpuesta de ampliación"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Ventana de ampliación"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controles de ampliación de la ventana"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Controles del dispositivo"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Controles de dispositivos"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Agrega controles para los dispositivos conectados"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles del dispositivo"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles de dispositivos"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Mantén presionado el botón de encendido para acceder a los controles"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Elige la app para agregar los controles"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Se quitaron todos los controles"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"No se cargó la lista completa de controles."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Otros"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Agregar a controles del dispositivo"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Agregar a controles de dispositivos"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Agregar a favoritos"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"La app <xliff:g id="APP">%s</xliff:g> sugirió que agregaras este control a favoritos."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controles actualizados"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 90787d0f20df..7e3fdc7868da 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -91,7 +91,7 @@ <string name="screenrecord_name" msgid="2596401223859996572">"Grabación de pantalla"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación continua de una sesión de grabación de la pantalla"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"¿Empezar a grabar?"</string> - <string name="screenrecord_description" msgid="1123231719680353736">"Mientras grabas, el sistema Android puede capturar información sensible que se muestre o se reproduzca en tu dispositivo, como contraseñas, datos de pago, fotos, mensajes y audios."</string> + <string name="screenrecord_description" msgid="1123231719680353736">"Mientras grabas, el sistema Android puede capturar información sensible que se muestre o se reproduzca en tu dispositivo, como contraseñas, datos de pago, fotos, mensajes y audio."</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"Grabar audio"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio del dispositivo"</string> <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sonido de tu dispositivo, como música, llamadas y tonos de llamada"</string> @@ -101,7 +101,7 @@ <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Grabando pantalla"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Grabando pantalla y audio"</string> <string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar toques en la pantalla"</string> - <string name="screenrecord_stop_text" msgid="6549288689506057686">"Toca para detener"</string> + <string name="screenrecord_stop_text" msgid="6549288689506057686">"Toca aquí para detener"</string> <string name="screenrecord_stop_label" msgid="72699670052087989">"Detener"</string> <string name="screenrecord_pause_label" msgid="6004054907104549857">"Pausar"</string> <string name="screenrecord_resume_label" msgid="4972223043729555575">"Seguir"</string> @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controla las burbujas en cualquier momento"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toca Gestionar para desactivar las burbujas de esta aplicación"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se ha actualizado la navegación del sistema. Para hacer cambios, ve a Ajustes."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Ajustes para actualizar la navegación del sistema"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecen arriba de la sección de conversaciones"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Muestran imagen de perfil en pantalla de bloqueo"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecen como burbuja sobre las aplicaciones"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrumpen No molestar"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Entendido"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Ventana de superposición de ampliación"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Ventana de ampliación"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ventana de controles de ampliación"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Controles del dispositivo"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Añade controles a tus dispositivos conectados"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles del dispositivo"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar control de dispositivos"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Mantén pulsado el botón de encendido para acceder a tus controles"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Elige una aplicación para añadir controles"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Todos los controles quitados"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"No se ha podido cargar la lista de los controles."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Otros"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Añadir a controles del dispositivo"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Añadir a control de dispositivos"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Añadir a favoritos"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"La aplicación <xliff:g id="APP">%s</xliff:g> ha sugerido este control para que lo añadas a tus favoritos."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controles actualizados"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index a2b687e22779..fa6447b20e71 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -100,7 +100,7 @@ <string name="screenrecord_start" msgid="330991441575775004">"Alusta"</string> <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Ekraanikuva salvestamine"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Ekraanikuva ja heli salvestamine"</string> - <string name="screenrecord_taps_label" msgid="1595690528298857649">"Kuva ekraanikuva puudutused"</string> + <string name="screenrecord_taps_label" msgid="1595690528298857649">"Kuva ekraanipuudutused"</string> <string name="screenrecord_stop_text" msgid="6549288689506057686">"Puudutage peatamiseks"</string> <string name="screenrecord_stop_label" msgid="72699670052087989">"Peata"</string> <string name="screenrecord_pause_label" msgid="6004054907104549857">"Peata"</string> @@ -945,7 +945,7 @@ <string name="instant_apps_title" msgid="8942706782103036910">"Rakendus <xliff:g id="APP">%1$s</xliff:g> töötab"</string> <string name="instant_apps_message" msgid="6112428971833011754">"Rakendus avati installimata."</string> <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Rakendus avati installimata. Lisateabe saamiseks puudutage."</string> - <string name="app_info" msgid="5153758994129963243">"Rakenduse teave"</string> + <string name="app_info" msgid="5153758994129963243">"Rakenduste teave"</string> <string name="go_to_web" msgid="636673528981366511">"Ava brauser"</string> <string name="mobile_data" msgid="4564407557775397216">"Mobiilne andmeside"</string> <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string> @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Juhtige mulle igal ajal"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Selle rakenduse puhul mullide väljalülitamiseks puudutage valikut Haldamine"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Selge"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Süsteemis navigeerimine on värskendatud. Muutmiseks avage jaotis Seaded."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Süsteemi navigeerimise värskendamiseks avage jaotis Seaded"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ooterežiim"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Kuvatakse vestluste jaotise kohal"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Lukustuskuval kuvatakse profiilipilt"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Kuvatakse rakenduste kohal hõljuva mullina"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Funktsiooni Mitte segada katkestamine"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Selge"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Suurendamisakna ülekate"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Suurendamisaken"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Suurendamisakna juhtelemendid"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Seadme juhtelemendid"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Seadmete juhtimisvidinad"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Lisage juhtelemendid ühendatud seadmete jaoks"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Seadme juhtelementide seadistamine"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Seadmete juhtimisvidinate seadistamine"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Juhtelementidele juurdepääsemiseks hoidke all toitenuppu"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Valige juhtelementide lisamiseks rakendus"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Kõik juhtnupud eemaldati"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Kõikide juhtelementide loendit ei saanud laadida."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Muu"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Seadme juhtelementide hulka lisamine"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Seadmete juhtimisvidinate hulka lisamine"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Lisa lemmikutesse"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> soovitas selle juhtnupu teie lemmikutesse lisada."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Juhtelemente värskendati"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 590cfaff3306..1d90e929fbae 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -999,25 +999,21 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrolatu burbuilak edonoiz"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Aplikazioaren burbuilak desaktibatzeko, sakatu Kudeatu"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ados"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> aplikazioaren ezarpenak"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Eguneratu da sistemaren nabigazioa. Aldaketak egiteko, joan Ezarpenak atalera."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistemaren nabigazioa eguneratzeko, joan Ezarpenak atalera"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Egonean"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Erakutsi elkarrizketen atalaren goialdean"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Erakutsi profileko argazkia pantaila blokeatuan"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Burbuila gainerakor gisa agertuko da aplikazioen gainean"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Eten ez molestatzeko modua"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Ados"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Lupa-leiho gainjarria"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Lupa-leihoa"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Lupa-leihoaren aukerak"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Gailua kontrolatzeko aukerak"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Gailuak kontrolatzeko widgetak"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Gehitu kontrolatzeko aukerak konektatutako gailuetan"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfiguratu gailua kontrolatzeko aukerak"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfiguratu gailuak kontrolatzeko widgetak"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Kontrol-aukerak atzitzeko, eduki sakatuta etengailua"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Aukeratu aplikazio bat kontrolatzeko aukerak gehitzeko"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1026,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Kontrolatzeko aukera guztiak kendu dira"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Ezin izan da kargatu kontrol guztien zerrenda."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Beste bat"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Gehitu gailua kontrolatzeko aukeretan"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Gehitu gailuak kontrolatzeko widgetetan"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Gehitu gogokoetan"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> aplikazioak aukera hau gogokoetan gehitzea iradoki du."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Eguneratu dira kontrolatzeko aukerak"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index a6e12bcaa7f0..5860af67e0e1 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"کنترل ابزارک اعلان در هرزمانی"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"برای خاموش کردن «ابزارک اعلان» از این برنامه، روی «مدیریت» ضربه بزنید"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"متوجهام"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"پیمایش سیستم بهروزرسانی شد. برای انجام تغییرات به «تنظیمات» بروید."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"برای بهروزرسانی پیمایش سیستم، به «تنظیمات» بروید"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"آمادهبهکار"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"نمایش در بالای بخش مکالمه"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"نمایش تصویر نمایه در صفحه قفل"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"بهشکل ابزارک اعلان شناور روی برنامهها ظاهر میشود"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"وقفه در «مزاحم نشوید»"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"متوجهام"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"پنجره همپوشانی بزرگنمایی"</string> <string name="magnification_window_title" msgid="4863914360847258333">"پنجره بزرگنمایی"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"کنترلهای پنجره بزرگنمایی"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index e15547a3fc6e..04204535dc08 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Muuta kuplien asetuksia milloin tahansa"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Valitse Hallinnoi, jos haluat poistaa kuplat käytöstä tästä sovelluksesta"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Selvä"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Järjestelmän navigointitapa vaihdettu. Voit muuttaa sitä asetuksista."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Vaihda järjestelmän navigointitapaa asetuksista"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Virransäästötila"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Näkyy keskusteluosion yläosassa"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Profiilikuva näkyy lukitusnäytöllä"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Näkyy kelluvana kuplana sovellusten päällä"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Keskeyttää Älä häiritse ‑tilan"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Selvä"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Suurennuksen peittoikkuna"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Suurennusikkuna"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Suurennusikkunan ohjaimet"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Laitteen säätimet"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Laitteiden hallinta"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Lisää säätimiä yhdistettyihin laitteisiisi"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Laitteen säätimien käyttöönotto"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Laitteiden hallinnan käyttöönotto"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Voit käyttää säätimiä painamalla virtapainiketta"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Valitse sovellus lisätäksesi säätimiä"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Kaikki säätimet poistettu"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Kaikkien säätimien luetteloa ei voitu ladata."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Muu"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Lisää laitteen säätimiin"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Lisää laitteiden hallintaan"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Lisää suosikkeihin"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> ehdotti tämän säätimen lisäämistä suosikkeihisi."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Säätimet päivitetty"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 737203104a1d..da44d8894251 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -999,25 +999,21 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Gérer les paramètres des bulles"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toucher Gérer pour désactiver les bulles de cette application"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Paramètres <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"La navigation système a été mise à jour. Pour apporter des modifications, accédez au menu Paramètres."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accédez au menu Paramètres pour mettre à jour la navigation système"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Veille"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aff. dans le haut de la section des conversations"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Afficher la photo de profil sur l\'écran verrouillé"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Sous forme de bulle flottante, par-dessus les applis"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrompre le mode Ne pas déranger"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Fenêtre d\'agrandissement superposée"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Fenêtre d\'agrandissement"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Commandes pour la fenêtre d\'agrandissement"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Commandes de l\'appareil"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Commandes de contrôle des appareils"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Ajoutez des commandes pour vos appareils connectés"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes de l\'appareil"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes de contrôle des appareils"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Maintenez l\'interrupteur enfoncé pour accéder à vos commandes"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'application pour laquelle ajouter des commandes"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1026,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Toutes les commandes ont été supprimées"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Impossible de charger la liste des commandes."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Autre"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Ajouter aux commandes de l\'appareil"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Ajouter aux commandes de contrôle des appareils"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Ajouter aux favoris"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"L\'application <xliff:g id="APP">%s</xliff:g> a suggéré d\'ajouter cette commande à vos favoris."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Commandes mises à jour"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 22830bc89669..0899e0971af4 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -91,7 +91,7 @@ <string name="screenrecord_name" msgid="2596401223859996572">"Enregistreur d\'écran"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement de l\'écran"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"Démarrer l\'enregistrement ?"</string> - <string name="screenrecord_description" msgid="1123231719680353736">"Pendant l\'enregistrement, le système Android peut capturer des informations sensibles affichées à l\'écran ou lues depuis votre appareil. Ceci inclut les mots de passe, les informations de paiement, les photos, les messages et les contenus audio."</string> + <string name="screenrecord_description" msgid="1123231719680353736">"Pendant l\'enregistrement, le système Android peut capturer toute information sensible affichée à l\'écran ou lue sur votre appareil. Ceci inclut les mots de passe, les informations de paiement, les photos, les messages et les contenus audio."</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"Enregistrer les contenus audio"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Appareil"</string> <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sons provenant de l\'appareil, tels que la musique, les appels et les sonneries"</string> @@ -100,7 +100,7 @@ <string name="screenrecord_start" msgid="330991441575775004">"Démarrer"</string> <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Enregistrement de l\'écran"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Enregistrement de l\'écran et des contenus audio"</string> - <string name="screenrecord_taps_label" msgid="1595690528298857649">"Afficher les éléments touchés à l\'écran"</string> + <string name="screenrecord_taps_label" msgid="1595690528298857649">"Afficher les points de l\'écran touchés"</string> <string name="screenrecord_stop_text" msgid="6549288689506057686">"Appuyez ici pour arrêter"</string> <string name="screenrecord_stop_label" msgid="72699670052087989">"Arrêter"</string> <string name="screenrecord_pause_label" msgid="6004054907104549857">"Pause"</string> @@ -508,7 +508,7 @@ <string name="manage_notifications_text" msgid="6885645344647733116">"Gérer"</string> <string name="manage_notifications_history_text" msgid="57055985396576230">"Historique"</string> <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notifications silencieuses"</string> - <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notifications sonores"</string> + <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notifications d\'alerte"</string> <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string> <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Effacer toutes les notifications silencieuses"</string> <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications suspendues par le mode Ne pas déranger"</string> @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Contrôler les paramètres des bulles"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Appuyez sur \"Gérer\" pour désactiver les bulles de cette application"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigation système mise à jour. Pour apporter des modifications, accédez aux paramètres."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accédez aux paramètres pour mettre à jour la navigation système"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Mode Veille imminent"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"En haut de la liste des conversations"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Photo de profil sur l\'écran de verrouillage"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Sous forme d\'info-bulle au-dessus des applications"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrompre Ne pas déranger"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Fenêtre de superposition de l\'agrandissement"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Fenêtre d\'agrandissement"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Fenêtre des commandes d\'agrandissement"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Commandes de l\'appareil"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Commandes de contrôle des appareils"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Ajouter des commandes pour vos appareils connectés"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes de l\'appareil"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes de contrôle des appareils"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Appuyez de manière prolongée sur le bouton Marche/Arrêt pour accéder aux commandes"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'appli pour laquelle ajouter des commandes"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Toutes les commandes ont été supprimées"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Impossible de charger toutes les commandes."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Autre"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Ajouter aux commandes de l\'appareil"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Ajouter aux commandes de contrôle des appareils"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Ajouter aux favoris"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> a suggéré d\'ajouter cette commande aux favoris."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Commandes mises à jour"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 1f2b827e6e1e..2e910c77f346 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlar as burbullas en calquera momento"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Para desactivar as burbullas nesta aplicación, toca Xestionar"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Entendido"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Actualizouse a navegación do sistema. Para facer cambios, vai a Configuración."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Para actualizar a navegación do sistema, vai a Configuración"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Mostrar na parte superior da sección de conversas"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrar imaxe do perfil na pantalla de bloqueo"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Mostrar como burbulla flotante sobre outras apps"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interromper modo Non molestar"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Listo"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Ampliación da ventá de superposición"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Ventá de superposición"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controis de ampliación da ventá"</string> <string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Engade controis para os dispositivos conectados"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar control de dispositivos"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar o control de dispositivos"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Mantén premido o botón de acendido para acceder aos controis"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Escolle unha aplicación para engadir controis"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 72120ce0677c..715c40b93c4a 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -707,8 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"બબલ"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"તમને સાઉન્ડ અથવા વાઇબ્રેશન વિના ફોકસ કરવામાં સહાય કરે છે."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"સાઉન્ડ અથવા વાઇબ્રેશન વિના તમારું ધ્યાન દોરે છે."</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"સાઉન્ડ અથવા વાઇબ્રેશન વિના તમારું ધ્યાન દોરે છે. ડિફૉલ્ટ તરીકે <xliff:g id="APP_NAME">%1$s</xliff:g> બબલની વાતચીત."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ફ્લોટિંગ શૉર્ટકટથી આ કન્ટેન્ટ પર તમારું ધ્યાન દોરી રાખે છે."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"વાતચીત વિભાગની ટોચ પર બતાવે છે અને બબલ તરીકે દેખાય છે."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"સેટિંગ"</string> @@ -1000,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"બબલને કોઈપણ સમયે નિયંત્રિત કરો"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"આ ઍપમાંથી બબલને બંધ કરવા માટે મેનેજ કરો પર ટૅપ કરો"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"સમજાઈ ગયું"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"સિસ્ટમ નૅવિગેશન અપડેટ કર્યું. ફેરફારો કરવા માટે, સેટિંગ પર જાઓ."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"સિસ્ટમ નૅવિગેશનને અપડેટ કરવા માટે સેટિંગ પર જાઓ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"સ્ટૅન્ડબાય"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"વાતચીત વિભાગની ટોચ પર બતાવો"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"લૉક સ્ક્રીન પર પ્રોફાઇલ ફોટો બતાવો"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ઍપની ટોચ પર તરતા બબલ તરીકે દેખાય છે"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"ખલેલ પાડશો નહીં સેટિંગમાં હસ્તક્ષેપ કરી શકે છે"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"સમજાઈ ગયું"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"વિસ્તૃતીકરણ ઓવરલે વિંડો"</string> <string name="magnification_window_title" msgid="4863914360847258333">"વિસ્તૃતીકરણ વિંડો"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"વિસ્તૃતીકરણ વિંડોના નિયંત્રણો"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index d0e600394ca3..af45c6805fb8 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -1001,25 +1001,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"जब चाहें, बबल्स को कंट्रोल करें"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"इस ऐप्लिकेशन पर बबल्स को बंद करने के लिए \'प्रबंधित करें\' पर टैप करें"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ठीक है"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेविगेशन अपडेट हो गया. बदलाव करने के लिए \'सेटिंग\' पर जाएं."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेविगेशन अपडेट करने के लिए \'सेटिंग\' में जाएं"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टैंडबाई"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"बातचीत सेक्शन में सबसे ऊपर दिखाएं"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो दिखाएं"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"खास बातचीत फ़्लोटिंग बबल की तरह ऐप्लिकेशन के ऊपर दिखेंगी"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'परेशान न करें\' मोड में रुकावट"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"ठीक है"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Magnification Overlay Window"</string> <string name="magnification_window_title" msgid="4863914360847258333">"स्क्रीन को बड़ा करके दिखाने वाली विंडो"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"स्क्रीन को बड़ा करके दिखाने वाली विंडो के नियंत्रण"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"डिवाइस के कंट्रोल"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"डिवाइस कंट्रोल"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"कनेक्ट किए गए डिवाइस के लिए कंट्रोल जोड़ें"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"डिवाइस के कंट्रोल सेट अप करें"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"डिवाइस कंट्रोल सेट अप करें"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"कंट्रोल ऐक्सेस करने के लिए पावर बटन को दबाकर रखें"</string> <string name="controls_providers_title" msgid="6879775889857085056">"कंट्रोल जोड़ने के लिए ऐप्लिकेशन चुनें"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1032,7 +1029,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"सभी कंट्रोल हटा दिए गए"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"सभी कंट्रोल की सूची लोड नहीं हो सकी."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"अन्य"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"डिवाइस के कंट्रोल में जोड़ें"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"डिवाइस कंट्रोल में जोड़ें"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"पसंदीदा में जोड़ें"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> आपको इस कंट्रोल को अपनी पसंदीदा में जोड़ने का सुझाव देता है."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"कंट्रोल अपडेट किए गए"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index cbffb1f055e3..7bcb22eceae8 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -1004,23 +1004,19 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljanje oblačićima u svakom trenutku"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dodirnite Upravljanje da biste isključili oblačiće iz ove aplikacije"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Shvaćam"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Postavke za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Ažurirana je navigacija sustavom. Možete je promijeniti u Postavkama."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Navigaciju sustavom možete ažurirati u Postavkama"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazuje se pri vrhu odjeljka razgovora"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazuje profilnu sliku na zaključanom zaslonu"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Prikazuje se kao lebdeći oblačić iznad aplikacija"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Prekida Ne uznemiravaj"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Shvaćam"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Prozor preklapanja povećavanja"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za povećavanje"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za povećavanje"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Upravljanje uređajem"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodavanje kontrola za povezane uređaje"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Postavljanje kontrola uređaja"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Dulje pritisnite tipku za uključivanje/isključivanje da biste pristupili kontrolama"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 480228bb1bb1..b5e6474aa343 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Buborékok vezérlése bármikor"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"A Kezelés gombra koppintva kapcsolhatja ki az alkalmazásból származó buborékokat"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Értem"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"A rendszer-navigáció módja megváltozott. Módosításához nyissa meg a Beállításokat."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"A rendszer-navigációs lehetőségeket a Beállításokban módosíthatja"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Készenléti mód"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"A beszélgetések szakaszának tetején jelennek meg"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Megjelenítik a profilképet a lezárási képernyőn"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Buborékként jelennek meg az alkalmazások felett"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Megszakítják a Ne zavarjanak módot"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Értem"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Nagyítási fedvény ablaka"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Nagyítás ablaka"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Nagyítási vezérlők ablaka"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 0bf29edad983..f2ec4b9960ca 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -87,7 +87,7 @@ <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Չհաջողվեց պահել սքրինշոթը անբավարար հիշողության պատճառով"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Հավելվածը կամ ձեր կազմակերպությունը չի թույլատրում սքրինշոթի ստացումը"</string> <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Փակել սքրինշոթը"</string> - <string name="screenshot_preview_description" msgid="7606510140714080474">"Սքրինշոթի նախատեսք"</string> + <string name="screenshot_preview_description" msgid="7606510140714080474">"Սքրինշոթի նախադիտում"</string> <string name="screenrecord_name" msgid="2596401223859996572">"Էկրանի տեսագրիչ"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Էկրանի տեսագրման աշխատաշրջանի ընթացիկ ծանուցում"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"Սկսե՞լ տեսագրումը"</string> @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ամպիկների կարգավորումներ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Հպեք «Կառավարել» կոճակին՝ այս հավելվածի ամպիկներն անջատելու համար։"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Եղավ"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Համակարգի նավիգացիան թարմացվեց: Փոփոխություններ անելու համար անցեք կարգավորումներ:"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Թարմացրեք համակարգի նավիգացիան կարգավորումներում"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Սպասման ռեժիմ"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Ցուցադրվում են «Խոսակցություններ» բաժնի վերևում"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Ցուցադրում են պրոֆիլի նկարը կողպէկրանին"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Հայտնվում են որպես լողացող ամպիկ հավելվածների վրայից"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ընդհատում են «Չանհանգստացնել» ռեժիմը"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Եղավ"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Խոշորացման պատուհանի վրադրում"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Խոշորացման պատուհան"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Խոշորացման պատուհանի կառավարման տարրեր"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Սարքի կառավարման տարրեր"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Սարքերի կառավարման տարրեր"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Ավելացրեք կառավարման տարրեր ձեր միացված սարքերի համար"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Սարքի կառավարման տարրերի կարգավորում"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Սարքերի կառավարման տարրերի կարգավորում"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Սեղմած պահեք սնուցման կոճակը՝ կառավարման տարրերը բացելու համար"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Ընտրեք հավելված` կառավարման տարրեր ավելացնելու համար"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Կառավարման բոլոր տարրերը հեռացվեցին"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Չհաջողվեց բեռնել բոլոր կառավարների ցանկը։"</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Այլ"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Ավելացրեք սարքի կառավարման տարրերում"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Ավելացրեք սարքերի կառավարման տարրերում"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Ավելացնել ընտրանիում"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> հավելվածն առաջարկում է ավելացնել այս կառավարը ձեր ընտրանիում։"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Կառավարման տարրերը թարմացվեցին"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index ddcbcabdea99..f9126db5f131 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -999,19 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrol balon kapan saja"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Ketuk Kelola untuk menonaktifkan balon dari aplikasi ini"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Oke"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Setelan <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigasi sistem diupdate. Untuk melakukan perubahan, buka Setelan."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Buka Setelan untuk mengupdate navigasi sistem"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Siaga"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Muncul di atas bagian percakapan"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Menampilkan gambar profil di layar kunci"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Muncul sebagai balon mengambang di atas aplikasi"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Mengganggu fitur Jangan Ganggu"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Oke"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Jendela Overlay Pembesaran"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Jendela Pembesaran"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrol Jendela Pembesaran"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index b9c8c055f537..e8e5b7af7b90 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Hægt er að stjórna blöðrum hvenær sem er"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Ýttu á „Stjórna“ til að slökkva á blöðrum frá þessu forriti"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ég skil"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Kerfisstjórnun uppfærð. Þú getur breytt þessu í stillingunum."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Farðu í stillingar til að uppfæra kerfisstjórnun"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Biðstaða"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Sýna yfir samtalshluta"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Sýna prófílmynd á lásskjá"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Birta sem fljótandi blöðru yfir forritum"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Stöðva „Ónáðið ekki“"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Ég skil"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Stækkun yfirglugga"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Stækkunargluggi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Stækkunarstillingar glugga"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Tækjastýringar"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Tækjastjórnun"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Bæta við stýringum fyrir tengd tæki"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Setja upp tækjastýringar"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Setja upp tækjastjórnun"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Haltu inni aflrofanum til að sjá stýringarnar þínar"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Veldu forrit til að bæta við stýringum"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Allar stýringar fjarlægðar"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Ekki tókst að hlaða lista yfir allar stýringar."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Annað"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Bæta við tækjastýringar"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Bæta við tækjastjórnun"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Bæta við uppáhald"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> stakk upp á að bæta þessari stýringu við uppáhald."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Stýringar uppfærðar"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 5f815d1c6e13..c4b167bff07a 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -999,25 +999,21 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlla le bolle in qualsiasi momento"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tocca Gestisci per disattivare le bolle dall\'app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Impostazioni <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigazione del sistema aggiornata. Per apportare modifiche, usa le Impostazioni."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Usa le Impostazioni per aggiornare la navigazione del sistema"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Appaiono in cima alla sezione delle conversazioni"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrano immagine profilo in schermata di blocco"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Vengono mostrate come bolle mobili sopra le app"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrompono la modalità Non disturbare"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Finestra overlay ingrandimento"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Finestra ingrandimento"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Finestra controlli di ingrandimento"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Controlli del dispositivo"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Controllo dei dispositivi"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Aggiungi controlli per i dispositivi connessi"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configura i controlli del dispositivo"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configura il controllo dei dispositivi"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Tieni premuto il tasto di accensione per accedere ai controlli"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Scegli un\'app per aggiungere controlli"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1026,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Tutti i controlli sono stati rimossi"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Impossibile caricare l\'elenco di tutti i controlli."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Altro"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Aggiungi ai controlli del dispositivo"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Aggiungi al controllo dei dispositivi"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Aggiungi ai preferiti"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> ha suggerito di aggiungere questo controllo ai preferiti."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controlli aggiornati"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index fe94f6acca94..894bb03cacb0 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -87,8 +87,7 @@ <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"לא היה מספיק מקום לשמור את צילום המסך"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"האפליקציה או הארגון שלך אינם מתירים ליצור צילומי מסך"</string> <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"סגירת צילום מסך"</string> - <!-- no translation found for screenshot_preview_description (7606510140714080474) --> - <skip /> + <string name="screenshot_preview_description" msgid="7606510140714080474">"תצוגה מקדימה של צילום מסך"</string> <string name="screenrecord_name" msgid="2596401223859996572">"מקליט המסך"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"להתחיל את ההקלטה?"</string> @@ -714,8 +713,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"בועה"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"עוזרת להתרכז ללא צלילים או רטט."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"מעוררת תשומת לב באמצעות צלילים או רטט."</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"מעוררת תשומת לב באמצעות צלילים או רטט. שיחות מהאפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מופיעות בבועות כברירת מחדל."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"מעוררת תשומת לב באמצעות קיצור דרך צף לתוכן הזה."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"מוצגת בחלק העליון של קטע השיחה ומופיעה כבועה."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"הגדרות"</string> @@ -1011,25 +1009,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"שליטה בבועות, בכל זמן"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"יש להקיש על \'ניהול\' כדי להשבית את הבועות מהאפליקציה הזו"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"הבנתי"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"הניווט במערכת עודכן. אפשר לערוך שינויים דרך ההגדרות."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"יש לעבור להגדרות כדי לעדכן את הניווט במערכת"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"המתנה"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"מופיעות בחלק העליון של קטע השיחות"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"מציגות תמונת פרופיל במסך הנעילה"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"מופיעות כבועה צפה מעל האפליקציות שלך"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"גוברות על ההגדרה \'נא לא להפריע\'"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"הבנתי"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"חלון ליצירת שכבת-על להגדלה"</string> <string name="magnification_window_title" msgid="4863914360847258333">"חלון הגדלה"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"בקרות של חלון ההגדלה"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"פקדי המכשיר"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"פקדי מכשירים"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"יש להוסיף פקדים למכשירים המחוברים"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"הגדרה של פקדי המכשיר"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"הגדרה של פקדי מכשירים"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"יש ללחוץ לחיצה ארוכה על לחצן ההפעלה כדי לגשת לבקרים"</string> <string name="controls_providers_title" msgid="6879775889857085056">"יש לבחור אפליקציה כדי להוסיף פקדים"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1044,7 +1039,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"כל הפקדים הוסרו"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"לא ניתן היה לטעון את הרשימה של כל הפקדים."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"אחר"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"הוספה לפקדי המכשיר"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"הוספה לפקדי המכשירים"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"הוספה למועדפים"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"בקרה זו הוצעה על ידי <xliff:g id="APP">%s</xliff:g> להוספה למועדפים."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"הפקדים עודכנו"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 94e80a604bd4..74e996b1fd7d 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -999,19 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"いつでもバブルを管理"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"このアプリからのバブルをオフにするには、[管理] をタップしてください"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> の設定"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"システム ナビゲーションを更新しました。変更するには [設定] に移動してください。"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"システム ナビゲーションを更新するには [設定] に移動してください"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"スタンバイ"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"会話セクションの一番上にバブル表示"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ロック画面にプロフィール写真を表示"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"他のアプリに重ねてフローティング バブルとして表示"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"サイレント モードに割り込み"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"拡大オーバーレイ ウィンドウ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"拡大ウィンドウ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"拡大ウィンドウ コントロール"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index dd3c267b1682..d1b3334ab88b 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -999,19 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ბუშტების ნებისმიერ დროს გაკონტროლება"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ამ აპის ბუშტების გამოსართავად შეეხეთ „მართვას“"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"გასაგებია"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-ის პარამეტრები"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"სისტემური ნავიგაცია განახლდა. ცვლილებების შესატანად გადადით პარამეტრებზე."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"სისტემური ნავიგაციის გასაახლებლად გადადით პარამეტრებზე"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"მოლოდინის რეჟიმი"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"მიმოწერის სექციის ზემოთ ჩვენება"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ჩაკეტილ ეკრანზე პროფილის სურათის ჩვენება"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"გამოჩნდება მოლივლივე ბუშტის სახით აპების ზემოდან"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"„არ შემაწუხოთ“ რეჟიმის შეწყვეტა"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"გასაგებია"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"გადიდების გადაფარვის ფანჯარა"</string> <string name="magnification_window_title" msgid="4863914360847258333">"გადიდების ფანჯარა"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"გადიდების კონტროლის ფანჯარა"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index d88e79de417f..82f77530f1ab 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -87,8 +87,7 @@ <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Жадтағы шектеулі бос орынға байланысты скриншот сақталмайды"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Қолданба немесе ұйым скриншоттар түсіруге рұқсат етпейді"</string> <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Скриншотты жабу"</string> - <!-- no translation found for screenshot_preview_description (7606510140714080474) --> - <skip /> + <string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотты алдын ала қарау"</string> <string name="screenrecord_name" msgid="2596401223859996572">"Экран жазғыш"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды бейнеге жазудың ағымдағы хабарландыруы"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"Жазу басталсын ба?"</string> @@ -1000,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Қалқыма хабарларды реттеу"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Бұл қолданбадан қалқыма хабарларды өшіру үшін \"Басқару\" түймесін түртіңіз."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Түсінікті"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Жүйе навигациясы жаңартылды. Өзгерту енгізу үшін \"Параметрлер\" бөліміне өтіңіз."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Жүйе навигациясын жаңарту үшін \"Параметрлер\" бөліміне өтіңіз."</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Күту режимі"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Сөйлесу бөлімінің жоғарғы жағында көрсетіледі."</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Профиль суреті құлыптаулы экранда көрсетіледі."</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Қолданбалар терезесінің бергі жағынан қалқыма хабарлар түрінде көрсетіледі."</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\"Мазаламау\" режимінде көрсетіледі."</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Түсінікті"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Ұлғайту терезесін қабаттастыру"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Ұлғайту терезесі"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ұлғайту терезесінің басқару элементтері"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Құрылғыны басқару элементтері"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Құрылғы басқару виджеттері"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Жалғанған құрылғыларға басқару элементтерін енгізу"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Құрылғыны басқару элементтерін реттеу"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Құрылғы басқару виджеттерін реттеу"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Басқару элементтерін шығару үшін қуат түймесін басып тұрыңыз."</string> <string name="controls_providers_title" msgid="6879775889857085056">"Басқару элементтері енгізілетін қолданбаны таңдаңыз"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1031,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Барлық басқару элементтері өшірілді."</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Барлық басқару элементі тізімі жүктелмеді."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Басқа"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Құрылғыны басқару элементтеріне қосу"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Құрылғы басқару виджеттеріне қосу"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Таңдаулыларға қосу"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> қолданбасы бұл басқару элементін таңдаулыларға қосып қоюды ұсынды."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Басқару элементтері жаңартылды"</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index fb430a693832..aa1d77660cc1 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"គ្រប់គ្រងពពុះបានគ្រប់ពេល"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ចុច \"គ្រប់គ្រង\" ដើម្បីបិទពពុះពីកម្មវិធីនេះ"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"យល់ហើយ"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"បានធ្វើបច្ចុប្បន្នភាពការរុករកក្នុងប្រព័ន្ធ។ ដើម្បីធ្វើការផ្លាស់ប្ដូរ សូមចូលទៅកាន់ការកំណត់។"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ចូលទៅកាន់ការកំណត់ ដើម្បីធ្វើបច្ចុប្បន្នភាពការរុករកក្នុងប្រព័ន្ធ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ផ្អាកដំណើរការ"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"បង្ហាញនៅខាងលើផ្នែកសន្ទនា"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"បង្ហាញរូបភាពកម្រងព័ត៌មាននៅលើអេក្រង់ចាក់សោ"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"បង្ហាញជាពពុះអណ្ដែតនៅផ្នែកខាងលើនៃកម្មវិធី"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"ផ្អាកមុខងារកុំរំខាន"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"យល់ហើយ"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"វិនដូត្រួតគ្នាលើការពង្រីក"</string> <string name="magnification_window_title" msgid="4863914360847258333">"វិនដូការពង្រីក"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"វិនដូគ្រប់គ្រងការពង្រីក"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"ការគ្រប់គ្រងឧបករណ៍"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"ផ្ទាំងគ្រប់គ្រងឧបករណ៍"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"បញ្ចូលការគ្រប់គ្រងសម្រាប់ឧបករណ៍ដែលបានភ្ជាប់របស់អ្នក"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"រៀបចំការគ្រប់គ្រងឧបករណ៍"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"រៀបចំផ្ទាំងគ្រប់គ្រងឧបករណ៍"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"សង្កត់ប៊ូតុងថាមពលឱ្យជាប់ ដើម្បីចូលប្រើការគ្រប់គ្រងរបស់អ្នក"</string> <string name="controls_providers_title" msgid="6879775889857085056">"ជ្រើសរើសកម្មវិធី ដើម្បីបញ្ចូលការគ្រប់គ្រង"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"បានលុបការគ្រប់គ្រងទាំងអស់ហើយ"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"មិនអាចផ្ទុកបញ្ជីនៃការគ្រប់គ្រងទាំងអស់បានទេ។"</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"ផ្សេងៗ"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"បញ្ចូលទៅក្នុងការគ្រប់គ្រងឧបករណ៍"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"បញ្ចូលទៅក្នុងផ្ទាំងគ្រប់គ្រងឧបករណ៍"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"បញ្ចូលទៅក្នុងសំណព្វ"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> បានណែនាំឱ្យបញ្ចូលការគ្រប់គ្រងនេះទៅក្នុងសំណព្វរបស់អ្នក។"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"បានធ្វើបច្ចុប្បន្នភាពការគ្រប់គ្រង"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index f5569bb5f47e..6fb7a1f648f9 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಬಬಲ್ಸ್ ಅನ್ನು ನಿಯಂತ್ರಿಸಿ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ಈ ಆ್ಯಪ್ನಿಂದ ಬಬಲ್ಸ್ ಅನ್ನು ಆಫ್ ಮಾಡಲು ನಿರ್ವಹಿಸಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ಅರ್ಥವಾಯಿತು"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಲು, ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಹೋಗಿ."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ್ ಅಪ್ಡೇಟ್ ಮಾಡಲು ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಹೋಗಿ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ಸ್ಟ್ಯಾಂಡ್ಬೈ"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"ಸಂಭಾಷಣೆ ವಿಭಾಗದ ಮೇಲ್ಭಾಗದಲ್ಲಿ ತೋರಿಸಿ"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಪ್ರೊಫೈಲ್ ಚಿತ್ರವನ್ನು ತೋರಿಸಿ"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ಆ್ಯಪ್ಗಳ ಮೇಲ್ಭಾಗದಲ್ಲಿ ತೇಲುವ ಬಬಲ್ನಂತೆ ಗೋಚರಿಸಲಿ"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"ಅಡಚಣೆ ಮಾಡಬೇಡ ಅನ್ನು ಅಡ್ಡಿಪಡಿಸಿ"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"ಅರ್ಥವಾಯಿತು"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"ವರ್ಧನೆಯ ಓವರ್ಲೇ ವಿಂಡೋ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"ವರ್ಧನೆಯ ವಿಂಡೋ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ವರ್ಧನೆಯ ವಿಂಡೋ ನಿಯಂತ್ರಣಗಳು"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 7c9f0744114a..f8e6b1f54066 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"언제든지 대화창을 제어하세요"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"이 앱에서 대화창을 사용 중지하려면 관리를 탭하세요."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"확인"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"시스템 탐색이 업데이트되었습니다. 변경하려면 설정으로 이동하세요."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"설정으로 이동하여 시스템 탐색을 업데이트하세요."</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"대기"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"대화 섹션의 상단에 표시"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"잠금 화면에서 프로필 사진 표시"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"앱 상단에서 플로팅 대화창으로 표시"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"방해 금지 모드 제외"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"확인"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"확대 오버레이 창"</string> <string name="magnification_window_title" msgid="4863914360847258333">"확대 창"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"확대 창 컨트롤"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"기기 컨트롤"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"기기 제어"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"연결된 기기의 컨트롤을 추가합니다."</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"기기 컨트롤 설정"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"기기 제어 설정"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"전원 버튼을 길게 눌러 컨트롤에 액세스하세요."</string> <string name="controls_providers_title" msgid="6879775889857085056">"컨트롤을 추가할 앱을 선택하세요"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"모든 컨트롤 삭제됨"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"전체 컨트롤 목록을 로드할 수 없습니다."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"기타"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"기기 컨트롤에 추가"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"기기 제어에 추가"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"즐겨찾기에 추가"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g>에서 이 제어 기능을 즐겨찾기에 추가할 것을 제안합니다."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"컨트롤 업데이트됨"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 1c8d5293b7f2..ae6c50adf7bd 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -87,8 +87,7 @@ <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"Сактагычта бош орун аз болгондуктан, скриншот сакталбай жатат"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Скриншот тартууга колдонмо же ишканаңыз тыюу салган."</string> <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Скриншотту четке кагуу"</string> - <!-- no translation found for screenshot_preview_description (7606510140714080474) --> - <skip /> + <string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотту алдын ала көрүү"</string> <string name="screenrecord_name" msgid="2596401223859996572">"экрандан видео жаздырып алуу"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"Жаздырып башталсынбы?"</string> @@ -1000,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Калкып чыкма билдирмелерди каалаган убакта көзөмөлдөңүз"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Бул колдонмодогу калкып чыкма билдирмелерди өчүрүү үчүн \"Башкарууну\" басыңыз"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Түшүндүм"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Тутум чабыттоосу жаңырды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Тутум чабыттоосун жаңыртуу үчүн Жөндөөлөргө өтүңүз"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Көшүү режими"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Жазышуу бөлүмүнүн үстүндө көрсөтүү"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Профилдин сүрөтүн кулпуланган экранда көрсөтүү"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Калкым чыкма билдирме катары көрсөтүү"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\"Тынчымды алба\" режими үзгүлтүккө учурайт"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Түшүндүм"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Чоңойтуу терезесин үстүнө коюу"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Чоңойтуу терезеси"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Чоңойтуу терезесин башкаруу каражаттары"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Түзмөктү көзөмөлдөө элементтери"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Түзмөктү башкаруу элементтери"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Байланыштырылган түзмөктөрүңүз үчүн көзөмөлдөрдү кошуңуз"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Түзмөктү көзөмөлдөө элементтерин жөндөө"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Түзмөктү башкаруу элементтерин жөндөө"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Көзөмөлдөргө өтүү үчүн, күйгүзүү/өчүрүү баскычын басып туруңуз"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Көзөмөлдөрдү кошуу үчүн колдонмо тандаңыз"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1031,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Бардык башкаруу элементтери өчүрүлдү"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Бардык көзөмөлдөрдүн тизмеси жүктөлгөн жок."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Башка"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Түзмөктү көзөмөлдөө элементтерине кошуу"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Түзмөктү башкаруу элементтерине кошуу"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Сүйүктүүлөргө кошуу"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> бул көзөмөлдү сүйүктүүлөргө кошууну сунуштады."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Башкаруу элементтери жаңырды"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 0e6f6e5c2d18..880ecea877a7 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -87,8 +87,7 @@ <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"ບໍ່ສາມາດຖ່າຍຮູບໜ້າຈໍໄດ້ເນື່ອງຈາກພື້ນທີ່ຈັດເກັບຂໍ້ມູນມີຈຳກັດ"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ແອັບ ຫຼື ອົງກອນຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ຖ່າຍຮູບໜ້າຈໍ"</string> <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ປິດຮູບໜ້າຈໍ"</string> - <!-- no translation found for screenshot_preview_description (7606510140714080474) --> - <skip /> + <string name="screenshot_preview_description" msgid="7606510140714080474">"ຕົວຢ່າງຮູບໜ້າຈໍ"</string> <string name="screenrecord_name" msgid="2596401223859996572">"ໂປຣແກຣມບັນທຶກໜ້າຈໍ"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ການແຈ້ງເຕືອນສຳລັບເຊດຊັນການບັນທຶກໜ້າຈໍໃດໜຶ່ງ"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"ເລີ່ມການບັນທຶກບໍ?"</string> @@ -1000,19 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ຄວບຄຸມຟອງຕອນໃດກໍໄດ້"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ແຕະຈັດການ ເພື່ອປິດຟອງຈາກແອັບນີ້"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ເຂົ້າໃຈແລ້ວ"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"ການຕັ້ງຄ່າ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ອັບເດດການນຳທາງລະບົບແລ້ວ. ເພື່ອປ່ຽນແປງ, ກະລຸນາໄປທີ່ການຕັ້ງຄ່າ."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ໄປທີ່ການຕັ້ງຄ່າເພື່ອອັບເດດການນຳທາງລະບົບ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ສະແຕນບາຍ"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"ສະແດງຢູ່ເທິງສຸດຂອງພາກສ່ວນການສົນທະນາ"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ສະແດງຮູບໂປຣໄຟລ໌ຢູ່ໜ້າຈໍລັອກ"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ປາກົດເປັນ bubble ລອຍຢູ່ເໜືອແອັບ"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"ລົບກວນໂໝດຫ້າມລົບກວນ"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"ເຂົ້າໃຈແລ້ວ"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"ໜ້າຈໍວາງທັບການຂະຫຍາຍ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"ໜ້າຈໍການຂະຫຍາຍ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ການຄວບຄຸມໜ້າຈໍການຂະຫຍາຍ"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index a4770f13a2f2..7374acd07afc 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -1009,19 +1009,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Bet kada valdyti burbulus"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Palieskite „Tvarkyti“, kad išjungtumėte burbulus šioje programoje"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Supratau"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistemos naršymo funkcijos atnaujintos. Jei norite pakeisti, eikite į skiltį „Nustatymai“."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Eikite į skiltį „Nustatymai“, kad atnaujintumėte sistemos naršymo funkcijas"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Budėjimo laikas"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Rodyti pokalbių skilties viršuje"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Rodyti profilio nuotrauką užrakinimo ekrane"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Rodyti kaip slankųjį debesėlį programų viršuje"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Pertraukti netrukdymo režimą"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Supratau"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Didinimo perdangos langas"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Didinimo langas"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Didinimo lango valdikliai"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index c1fe506f4499..2ace26779b95 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -1004,25 +1004,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Pārvaldīt burbuļus jebkurā laikā"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Pieskarieties pogai “Pārvaldīt”, lai izslēgtu burbuļus no šīs lietotnes."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Labi"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistēmas navigācija ir atjaunināta. Lai veiktu izmaiņas, atveriet iestatījumus."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Atveriet iestatījumus, lai atjauninātu sistēmas navigāciju"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gaidstāve"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Tiek rādītas sarunu sadaļas augšdaļā"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Tiek rādīts profila attēls bloķēšanas ekrānā"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Tiek rādītas kā peldošs burbulis virs lietotnēm"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Var tikt rādītas režīmā “Netraucēt”"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Labi"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Palielināšanas pārklājuma logs"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Palielināšanas logs"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Palielināšanas loga vadīklas"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Ierīces vadīklas"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Ierīču vadīklas"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Pievienojiet vadīklas pievienotajām ierīcēm"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Ierīces vadīklu iestatīšana"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Ierīču vadīklu iestatīšana"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Turiet nospiestu barošanas pogu, lai piekļūtu vadīklām."</string> <string name="controls_providers_title" msgid="6879775889857085056">"Izvēlieties lietotni, lai pievienotu vadīklas"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1036,7 +1033,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Visas vadīklas ir noņemtas"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Nevarēja ielādēt sarakstu ar visām vadīklām."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Cita"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Pievienošana ierīces vadīklām"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Pievienošana ierīču vadīklām"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Pievienot izlasei"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> ieteica pievienot šo vadīklu izlasei."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Vadīklas atjauninātas"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index ed2ec3ead87c..67392bb14d52 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Контролирајте ги балончињата во секое време"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Допрете „Управувајте“ за да ги исклучите балончињата од апликацијава"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Сфатив"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигацијата на системот е ажурирана. За да извршите промени, одете во „Поставки“."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Одете во „Поставки“ за да ја ажурирате навигацијата на системот"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Подготвеност"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Се прикажува најгоре во делот со разговори"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Се прикажува профилна слика на заклучен екран"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Се појавува како лебдечко балонче врз апликациите"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Прекинува „Не вознемирувај“"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Сфатив"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Прозорец за преклопување на зголемувањето"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Прозорец за зголемување"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Контроли на прозорец за зголемување"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 99488b2a7f7f..44a2aa11bbc2 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -707,8 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"ബബ്ൾ"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"ശബ്ദമോ വൈബ്രേഷനോ ഇല്ലാതെ ശ്രദ്ധ കേന്ദ്രീകരിക്കാൻ നിങ്ങളെ സഹായിക്കുന്നു."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"ശബ്ദമോ വെെബ്രേഷനോ ഉപയോഗിച്ച് നിങ്ങളുടെ ശ്രദ്ധ ക്ഷണിക്കുന്നു."</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"ശബ്ദമോ വൈബ്രേഷനോ ഉപയോഗിച്ച് നിങ്ങളുടെ ശ്രദ്ധ ക്ഷണിക്കുന്നു. <xliff:g id="APP_NAME">%1$s</xliff:g>-ൽ നിന്നുള്ള എല്ലാ സംഭാഷണങ്ങളും ഡിഫോൾട്ടായി ബബ്ൾ ആവുന്നു."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ഈ ഉള്ളടക്കത്തിലേക്ക് ഒരു ഫ്ലോട്ടിംഗ് കുറുക്കുവഴി ഉപയോഗിച്ച് നിങ്ങളുടെ ശ്രദ്ധ നിലനിർത്തുന്നു."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"സംഭാഷണ വിഭാഗത്തിന് മുകളിൽ ബബിളായി ദൃശ്യമാവുന്നു."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ക്രമീകരണം"</string> @@ -848,7 +847,7 @@ <string name="right_keycode" msgid="2480715509844798438">"വലതുവശത്തെ കീകോഡ്"</string> <string name="left_icon" msgid="5036278531966897006">"ഇടതുവശത്തെ ചിഹ്നം"</string> <string name="right_icon" msgid="1103955040645237425">"വലതുവശത്തെ ചിഹ്നം"</string> - <string name="drag_to_add_tiles" msgid="8933270127508303672">"ടൈലുകൾ ചേർക്കാൻ ക്ലിക്ക് ചെയ്ത് ഇഴയ്ക്കുക"</string> + <string name="drag_to_add_tiles" msgid="8933270127508303672">"ടൈലുകൾ ചേർക്കാൻ അമർത്തിപ്പിടിച്ച് വലിച്ചിടുക"</string> <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"ടൈലുകൾ പുനഃക്രമീകരിക്കാൻ അമർത്തിപ്പിടിച്ച് വലിച്ചിടുക"</string> <string name="drag_to_remove_tiles" msgid="4682194717573850385">"നീക്കംചെയ്യുന്നതിന് ഇവിടെ വലിച്ചിടുക"</string> <string name="drag_to_remove_disabled" msgid="933046987838658850">"നിങ്ങൾക്ക് ചുരുങ്ങിയത് <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ടൈലുകളെങ്കിലും വേണം"</string> @@ -1000,6 +999,8 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ബബിളുകൾ ഏതുസമയത്തും നിയന്ത്രിക്കുക"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ഈ ആപ്പിൽ നിന്നുള്ള ബബിളുകൾ ഓഫാക്കാൻ മാനേജ് ചെയ്യുക ടാപ്പ് ചെയ്യുക"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ലഭിച്ചു"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"സിസ്റ്റം നാവിഗേഷൻ അപ്ഡേറ്റ് ചെയ്തു. മാറ്റങ്ങൾ വരുത്താൻ ക്രമീകരണത്തിലേക്ക് പോവുക."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"സിസ്റ്റം നാവിഗേഷൻ അപ്ഡേറ്റ് ചെയ്യാൻ ക്രമീകരണത്തിലേക്ക് പോവുക"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"സ്റ്റാൻഡ്ബൈ"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 6cba12e16d74..0f17270ac3cc 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Дурын үед бөмбөлгийг хянаарай"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Энэ аппын бөмбөлгүүдийг унтраахын тулд Удирдах дээр товшино уу"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ойлголоо"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Системийн навигацыг шинэчиллээ. Өөрчлөхийн тулд Тохиргоо руу очно уу."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Системийн навигацыг шинэчлэхийн тулд Тохиргоо руу очно уу"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Зогсолтын горим"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Харилцан ярианы хэсгийн дээд талд харуулна"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Түгжигдсэн дэлгэц дээр профайлын зургийг харуулна"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Аппуудын дээр хөвөгч бөмбөлөг хэлбэрээр харагдана"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Бүү саад бол онцлогийг үл хэрэгсэн тасалдуулна"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Ойлголоо"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Томруулалтыг давхарласан цонх"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Томруулалтын цонх"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Томруулалтын цонхны хяналт"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index e33d8d7a6991..926b636439bc 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -707,8 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"बबल"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"आवाज किंवा व्हायब्रेशनशिवाय तुम्हाला लक्ष केंद्रित करण्यास मदत करते."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"आवाज किंवा व्हायब्रेशनने तुमचे लक्ष वेधून घेते."</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"आवाज किंवा व्हायब्रेशनने तुमचे लक्ष वेधून घेते. <xliff:g id="APP_NAME">%1$s</xliff:g> मधील संभाषणे बाय डीफॉल्ट बबल होतात."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"या आशयाच्या फ्लोटिंग शॉर्टकटसह तुमचे लक्ष केंद्रित करते."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"संभाषण विभागाच्या सर्वात वरती दिसते आणि बबलसारखे दिसते."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"सेटिंग्ज"</string> @@ -1000,6 +999,8 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"बबल कधीही नियंत्रित करा"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"या अॅपमधून बबल बंद करण्यासाठी व्यवस्थापित करा वर टॅप करा"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"समजले"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेव्हिगेशन अपडेट केले. बदल करण्यासाठी, सेटिंग्जवर जा."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेव्हिगेशन अपडेट करण्यासाठी सेटिंग्जवर जा"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टँडबाय"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 6f60bf08d8a7..efd2c851e409 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kawal gelembung pada bila-bila masa"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Ketik Urus untuk mematikan gelembung daripada apl ini"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigasi sistem dikemas kini. Untuk membuat perubahan, pergi ke Tetapan."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Pergi ke Tetapan untuk mengemas kini navigasi sistem"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tunggu sedia"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Tunjukkan di atas bahagian perbualan"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Tunjukkan gambar profil pada skrin kunci"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Dipaparkan sebagai gelembung terapung di atas apl"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ganggu Ciri Jangan Ganggu"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Tetingkap Tindanan Pembesaran"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Tetingkap Pembesaran"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kawalan Tetingkap Pembesaran"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index dab402e58adf..e4a07fbd7a76 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -999,25 +999,21 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ပူဖောင်းကွက်ကို အချိန်မရွေး ထိန်းချုပ်ရန်"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ဤအက်ပ်မှနေ၍ ပူဖောင်းများကို ပိတ်ရန်အတွက် \'စီမံရန်\' ကို တို့ပါ"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ရပါပြီ"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ဆက်တင်များ"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ပြီးပါပြီ။ အပြောင်းအလဲများ ပြုလုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ။"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"အသင့်အနေအထား"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"စကားဝိုင်းအပိုင်း၏ ထိပ်တွင်ပြရန်"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံကို ပြရန်"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"အက်ပ်အပေါ်တွင် မျောနေသောပူဖောင်းကွက်အဖြစ် ပေါ်မည်"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'မနှောင့်ယှက်ရ\' ကို ကြားဖြတ်ခြင်း"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Ok"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"ဝင်းဒိုး ထပ်ပိုးလွှာ ချဲ့ခြင်း"</string> <string name="magnification_window_title" msgid="4863914360847258333">"ဝင်းဒိုး ချဲ့ခြင်း"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ဝင်းဒိုး ထိန်းချုပ်မှုများ ချဲ့ခြင်း"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"စက်ပစ္စည်း ထိန်းချုပ်မှုများ"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"စက်ထိန်းစနစ်"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"သင့်ချိတ်ဆက်ထားသော စက်များအတွက် ထိန်းချုပ်မှုများ ထည့်ပါ"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"စက်ပစ္စည်းထိန်းချုပ်မှုများကို စနစ်ထည့်သွင်းခြင်း"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"စက်ထိန်းစနစ် ထည့်သွင်းခြင်း"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"သင့်ထိန်းချုပ်မှုများကို အသုံးပြုရန် \'ပါဝါ\' ခလုတ်ကို ဖိထားပါ"</string> <string name="controls_providers_title" msgid="6879775889857085056">"ထိန်းချုပ်မှုများထည့်ရန် အက်ပ်ရွေးခြင်း"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1026,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"ထိန်းချုပ်မှုအားလုံး ဖယ်ရှားလိုက်သည်"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"ထိန်းချုပ်မှုအားလုံး၏ စာရင်းကို ဖွင့်၍မရပါ။"</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"အခြား"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"စက်ပစ္စည်းထိန်းချုပ်မှုများသို့ ထည့်ရန်"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"စက်ထိန်းစနစ်သို့ ထည့်ရန်"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"အကြိုက်ဆုံးများသို့ ထည့်ရန်"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> သည် ဤခလုတ်ကို သင့်အကြိုက်ဆုံးများသို့ ထည့်ရန် အကြံပြုထားသည်။"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"ထိန်းချုပ်မှု အပ်ဒိတ်လုပ်ပြီးပြီ"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 7751e6fab11b..5ee07ae4dfc4 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrollér bobler når som helst"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Trykk på Administrer for å slå av bobler for denne appen"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Greit"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigeringen er oppdatert. For å gjøre endringer, gå til Innstillinger."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Gå til Innstillinger for å oppdatere systemnavigeringen"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ventemodus"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Vis øverst i samtaledelen"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Vis profilbildet på låseskjermen"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Vises som en svevende boble over apper"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Overstyr «Ikke forstyrr»"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Greit"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Overleggsvindu for forstørring"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Forstørringsvindu"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontroller for forstørringsvindu"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Enhetskontroller"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Enhetsstyring"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Legg til kontroller for de tilkoblede enhetene dine"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurer enhetskontroller"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurer enhetsstyring"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Hold inne av/på-knappen for å få tilgang til kontrollene"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Velg en app for å legge til kontroller"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Alle kontroller er fjernet"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Listen over alle kontroller kunne ikke lastes inn."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Annet"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Legg til i enhetskontroller"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Legg til i enhetsstyring"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Legg til som favoritt"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> har foreslått at du legger denne kontrollen til i favorittene dine."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Kontrollene er oppdatert"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index a7330f01ac03..ec7efdbc2b25 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -708,8 +708,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"बबल"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"तपाईंलाई आवाज वा कम्पनविना ध्यान केन्द्रित गर्न मद्दत गर्छ।"</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"ध्वनि वा कम्पनमार्फत तपाईंको ध्यान आकर्षित गर्छ।"</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"ध्वनि वा कम्पनमार्फत तपाईंको ध्यान आकर्षित गर्छ। <xliff:g id="APP_NAME">%1$s</xliff:g> का वार्तालापहरू पूर्वनिर्धारित रूपमा बबलमा देखाइन्छन्।"</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"फ्लोटिङ सर्टकटमार्फत यो सामग्रीतर्फ तपाईंको ध्यान आकर्षित गर्दछ।"</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"वार्तालाप खण्डको सिरानमा बबलका रूपमा देखा पर्छ।"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"सेटिङ"</string> @@ -1001,6 +1000,8 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"जुनसुकै बेला बबलहरू नियन्त्रण गर्नुहोस्"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"यो अनुप्रयोगबाट आएका बबलहरू निष्क्रिय पार्न व्यवस्थापन गर्नुहोस् नामक बटनमा ट्याप गर्नुहोस्"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"बुझेँ"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"प्रणालीको नेभिगेसन अद्यावधिक गरियो। परिवर्तन गर्न सेटिङमा जानुहोस्।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"प्रणालीको नेभिगेसन अद्यावधिक गर्न सेटिङमा जानुहोस्"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्ट्यान्डबाई"</string> @@ -1017,9 +1018,9 @@ <string name="magnification_overlay_title" msgid="6584179429612427958">"म्याग्निफिकेसन ओभरले विन्डो"</string> <string name="magnification_window_title" msgid="4863914360847258333">"म्याग्निफिकेसन विन्डो"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"म्याग्निफिकेसन विन्डोका नियन्त्रणहरू"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"यन्त्रले नियन्त्रण गर्न सक्ने कुराहरू"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"यन्त्र नियन्त्रण गर्ने विजेटहरू"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"आफ्ना जोडिएका यन्त्रहरूका लागि नियन्त्रण सुविधाहरू थप्नुहोस्"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"यन्त्रले नियन्त्रण गर्न सक्ने कुराहरू सेटअप गर्नुहोस्"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"यन्त्र नियन्त्रण गर्ने विजेटहरू सेटअप गर्नुहोस्"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"आफ्ना नियन्त्रणहरूमाथि पहुँच राख्न पावर बटन थिचिराख्नुहोस्"</string> <string name="controls_providers_title" msgid="6879775889857085056">"नियन्त्रणहरू थप्न अनुप्रयोग छनौट गर्नुहोस्"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1032,7 +1033,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"सबै नियन्त्रणहरू हटाइए"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"सबै नियन्त्रणहरूको सूची लोड गर्न सकिएन।"</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"अन्य"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"यन्त्रले नियन्त्रण गर्न सक्ने कुराहरूको सूचीमा थप्नुहोस्"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"यन्त्र नियन्त्रण गर्ने विजेटहरूको सूचीमा थप्नुहोस्"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"मन पर्ने कुराहरूमा थप्नुहोस्"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> ले यो नियन्त्रण तपाईंका मन पर्ने कुराहरूमा थप्न सुझाव सिफारिस गरेको छ।"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"नियन्त्रण सुविधाहरू अद्यावधिक गरिए"</string> diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml index 93aa2701ad07..2d5101104237 100644 --- a/packages/SystemUI/res/values-night/colors.xml +++ b/packages/SystemUI/res/values-night/colors.xml @@ -72,9 +72,14 @@ <color name="global_actions_alert_text">@color/GM2_red_300</color> <!-- Global screenshot actions --> - <color name="global_screenshot_button_background">@color/GM2_grey_900</color> + <color name="global_screenshot_button_background">@color/GM2_grey_800</color> <color name="global_screenshot_button_ripple">#42FFFFFF</color> - <color name="global_screenshot_button_text">@color/GM2_blue_300</color> + <color name="global_screenshot_button_text">#FFFFFF</color> + <color name="global_screenshot_button_border">@color/GM2_grey_600</color> + <color name="global_screenshot_button_icon">@color/GM2_blue_300</color> + <color name="global_screenshot_dismiss_background">@color/GM2_grey_800</color> + <color name="global_screenshot_dismiss_foreground">#FFFFFF</color> + <!-- Biometric dialog colors --> <color name="biometric_dialog_gray">#ff888888</color> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 98247a89aefe..dd730d44c694 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -999,25 +999,21 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Beheer bubbels wanneer je wilt"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tik op Beheren om bubbels van deze app uit te schakelen"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Instellingen voor <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systeemnavigatie geüpdatet. Als je wijzigingen wilt aanbrengen, ga je naar Instellingen."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ga naar Instellingen om de systeemnavigatie te updaten"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stand-by"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Worden bovenaan het gespreksgedeelte weergegeven"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Tonen profielafbeelding op vergrendelingsscherm"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Worden als zwevende ballon weergegeven vóór apps"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Onderbreken \'Niet storen\'"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Overlay voor vergrotingsvenster"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Vergrotingsvenster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Bediening van vergrotingsvenster"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Apparaatopties"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Apparaatbediening"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Bedieningselementen voor je gekoppelde apparaten toevoegen"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Apparaatopties instellen"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Apparaatbediening instellen"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Houd de aan/uit-knop ingedrukt voor toegang tot de bedieningselementen"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Kies de app waaraan je bedieningselementen wilt toevoegen"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1025,12 +1021,12 @@ <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> bedieningselement toegevoegd.</item> </plurals> <string name="controls_favorite_default_title" msgid="967742178688938137">"Bedieningselementen"</string> - <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Kies bedieningselementen die je vanaf het menu Voeding wilt kunnen gebruiken"</string> + <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Kies bedieningselementen die je vanaf het aan/uit-menu wilt kunnen gebruiken"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Houd vast en sleep om de bedieningselementen opnieuw in te delen"</string> <string name="controls_favorite_removed" msgid="5276978408529217272">"Alle bedieningselementen verwijderd"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Kan lijst met alle bedieningselementen niet laden."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Overig"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Toevoegen aan apparaatopties"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Toevoegen aan apparaatbediening"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Toevoegen aan favorieten"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> heeft voorgesteld dit bedieningselement toe te voegen aan je favorieten."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Bedieningselementen geüpdated"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 134c119194d9..cde084f3d27e 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -87,8 +87,7 @@ <string name="screenshot_failed_to_save_text" msgid="8344173457344027501">"ସୀମିତ ଷ୍ଟୋରେଜ୍ ସ୍ପେସ୍ ହେତୁ ସ୍କ୍ରୀନଶଟ୍ ସେଭ୍ ହୋଇପାରିବ ନାହିଁ"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ଆପ୍ କିମ୍ବା ସଂସ୍ଥା ଦ୍ୱାରା ସ୍କ୍ରୀନଶଟ୍ ନେବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string> <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ସ୍କ୍ରିନସଟ୍ ଖାରଜ କରନ୍ତୁ"</string> - <!-- no translation found for screenshot_preview_description (7606510140714080474) --> - <skip /> + <string name="screenshot_preview_description" msgid="7606510140714080474">"ସ୍କ୍ରିନସଟର ପ୍ରିଭ୍ୟୁ"</string> <string name="screenrecord_name" msgid="2596401223859996572">"ସ୍କ୍ରିନ୍ ରେକର୍ଡର୍"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ଏକ ସ୍କ୍ରିନ୍ ରେକର୍ଡ୍ ସେସନ୍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବେ?"</string> @@ -708,8 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"ବବଲ୍"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"ବିନା ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ରେ ଆପଣଙ୍କୁ ଫୋକସ୍ କରିବାରେ ସାହାଯ୍ୟ କରେ।"</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ ମାଧ୍ୟମରେ ଆପଣଙ୍କର ଧ୍ୟାନ ଆକର୍ଷିତ କରିଥାଏ।"</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ ମାଧ୍ୟମରେ ଆପଣଙ୍କ ଧ୍ୟାନ ଆକର୍ଷିତ କରିଥାଏ। <xliff:g id="APP_NAME">%1$s</xliff:g>ରୁ ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ ଡିଫଲ୍ଟ ଭାବରେ ବବଲ୍ ହୁଏ।"</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ଏହି ବିଷୟବସ୍ତୁ ପାଇଁ ଏକ ଭାସମାନ ସର୍ଟକଟ୍ ସହ ଆପଣଙ୍କର ଧ୍ୟାନ ଦିଅନ୍ତୁ।"</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"ଏହା ବାର୍ତ୍ତାଳାପ ବିଭାଗର ଶୀର୍ଷରେ ବବଲ୍ ଭାବେ ଦେଖାଯାଏ।"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ସେଟିଂସ୍"</string> @@ -1001,6 +999,8 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ଯେ କୌଣସି ସମୟରେ ବବଲଗୁଡ଼ିକ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ଏହି ଆପର ବବଲଗୁଡ଼ିକ ବନ୍ଦ କରିବା ପାଇଁ \'ପରିଚାଳନା କରନ୍ତୁ\' ବଟନରେ ଟାପ୍ କରନ୍ତୁ"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ବୁଝିଗଲି"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍ଡେଟ୍ ହୋଇଛି। ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ, ସେଟିଂସ୍କୁ ଯାଆନ୍ତୁ।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍ଡେଟ୍ କରିବା ପାଇଁ ସେଟିଂସ୍କୁ ଯାଆନ୍ତୁ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ଷ୍ଟାଣ୍ଡବାଏ"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 1c99ea365878..4e6247acd3ab 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -387,7 +387,7 @@ <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"ਵਾਈ-ਫਾਈ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"</string> <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ਚਮਕ"</string> <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"ਆਟੋ"</string> - <string name="quick_settings_inversion_label" msgid="5078769633069667698">"ਰੰਗ ਉਲਟੋ"</string> + <string name="quick_settings_inversion_label" msgid="5078769633069667698">"ਰੰਗ ਪਲਟਾਓ"</string> <string name="quick_settings_color_space_label" msgid="537528291083575559">"ਰੰਗ ਸੰਸ਼ੋਧਨ ਮੋਡ"</string> <string name="quick_settings_more_settings" msgid="2878235926753776694">"ਹੋਰ ਸੈਟਿੰਗਾਂ"</string> <string name="quick_settings_done" msgid="2163641301648855793">"ਹੋ ਗਿਆ"</string> @@ -648,7 +648,7 @@ <string name="status_bar_ethernet" msgid="5690979758988647484">"ਈਥਰਨੈਟ"</string> <string name="status_bar_alarm" msgid="87160847643623352">"ਅਲਾਰਮ"</string> <string name="status_bar_work" msgid="5238641949837091056">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string> - <string name="status_bar_airplane" msgid="4848702508684541009">"ਜਹਾਜ਼ ਮੋਡ"</string> + <string name="status_bar_airplane" msgid="4848702508684541009">"ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ"</string> <string name="add_tile" msgid="6239678623873086686">"ਟਾਇਲ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="broadcast_tile" msgid="5224010633596487481">"ਪ੍ਰਸਾਰਨ ਟਾਇਲ"</string> <string name="zen_alarm_warning_indef" msgid="5252866591716504287">"ਤੁਸੀਂ <xliff:g id="WHEN">%1$s</xliff:g> ਵਜੇ ਆਪਣਾ ਅਗਲਾ ਅਲਾਰਮ ਨਹੀਂ ਸੁਣੋਗੇ ਜਦੋਂ ਤੱਕ ਉਸਤੋਂ ਪਹਿਲਾਂ ਤੁਸੀਂ ਇਸਨੂੰ ਬੰਦ ਨਹੀਂ ਕਰਦੇ"</string> @@ -707,8 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"ਬੁਲਬੁਲਾ"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"ਤੁਹਾਨੂੰ ਬਿਨਾਂ ਧੁਨੀ ਅਤੇ ਥਰਥਰਾਹਟ ਦੇ ਫੋਕਸ ਕਰਨ ਵਿੱਚ ਮਦਦ ਕਰਦਾ ਹੈ।"</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"ਧੁਨੀ ਅਤੇ ਥਰਥਰਾਹਟ ਨਾਲ ਤੁਹਾਡਾ ਧਿਆਨ ਖਿੱਚਦੀ ਹੈ।"</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"ਧੁਨੀ ਅਤੇ ਥਰਥਰਾਹਟ ਨਾਲ ਤੁਹਾਡਾ ਧਿਆਨ ਖਿੱਚਦੀ ਹੈ। ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੌਰ \'ਤੇ <xliff:g id="APP_NAME">%1$s</xliff:g> ਬਬਲ ਤੋਂ ਗੱਲਾਂਬਾਤਾਂ।"</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ਇਸ ਸਮੱਗਰੀ ਦੇ ਅਸਥਿਰ ਸ਼ਾਰਟਕੱਟ ਨਾਲ ਆਪਣਾ ਧਿਆਨ ਕੇਂਦਰਿਤ ਰੱਖੋ।"</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"ਗੱਲਬਾਤ ਸੈਕਸ਼ਨ ਦੇ ਉੱਪਰ ਅਤੇ ਬਬਲ ਦੇ ਤੌਰ \'ਤੇ ਦਿਖਾਉਂਦਾ ਹੈ।"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ਸੈਟਿੰਗਾਂ"</string> @@ -1000,6 +999,8 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ਬਬਲ ਨੂੰ ਕਿਸੇ ਵੇਲੇ ਵੀ ਕੰਟਰੋਲ ਕਰੋ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ਇਸ ਐਪ \'ਤੇ ਬਬਲ ਬੰਦ ਕਰਨ ਲਈ \'ਪ੍ਰਬੰਧਨ ਕਰੋ\' \'ਤੇ ਟੈਪ ਕਰੋ"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ਸਮਝ ਲਿਆ"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਤਬਦੀਲੀਆਂ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ਸਟੈਂਡਬਾਈ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 81dff41479d5..e577fd2cf5ac 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -1009,25 +1009,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Zarządzaj dymkami w dowolnym momencie"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Kliknij Zarządzaj, aby wyłączyć dymki z tej aplikacji"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Nawigacja w systemie została zaktualizowana. Aby wprowadzić zmiany, otwórz Ustawienia."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Otwórz Ustawienia, by zaktualizować nawigację w systemie"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tryb gotowości"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Wyświetlają się u góry sekcji rozmów"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Pokazują zdjęcie profilowe na ekranie blokady"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Wyświetlane jako pływający dymek nad aplikacjami"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ignorują tryb Nie przeszkadzać"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Okno nakładki powiększenia"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Okno powiększenia"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Elementy sterujące okna powiększenia"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Sterowanie urządzeniem"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Sterowanie urządzeniami"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodaj elementy sterujące do połączonych urządzeń"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurowanie sterowania urządzeniem"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurowanie sterowania urządzeniami"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Przytrzymaj przycisk zasilania, aby uzyskać dostęp do elementów sterujących"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Wybierz aplikację, do której chcesz dodać elementy sterujące"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1042,7 +1039,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Usunięto wszystkie elementy sterujące"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Nie udało się wczytać listy elementów sterujących."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Inne"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Dodaj do sterowania urządzeniem"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Dodaj do sterowania urządzeniami"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Dodaj do ulubionych"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"Aplikacja <xliff:g id="APP">%s</xliff:g> zaproponowała dodanie tego elementu sterującego do ulubionych."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Zaktualizowano elementy sterujące"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index cd1cd2df6043..0544c50b2aa7 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -710,7 +710,7 @@ <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Chama sua atenção com som ou vibração. As conversas do app <xliff:g id="APP_NAME">%1$s</xliff:g> aparecem em balões por padrão."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Mantém sua atenção com um atalho flutuante para esse conteúdo."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Aparece na parte superior de uma seção de conversa e em forma de balão."</string> - <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Config."</string> + <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configurações"</string> <string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string> <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nenhum balão recente"</string> <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Os balões recentes e dispensados aparecerão aqui"</string> @@ -999,19 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controle os balões a qualquer momento"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toque em \"Gerenciar\" para desativar os balões desse app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ok"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Configurações de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Acesse as configurações para atualizar a navegação no sistema"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Em espera"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecer na parte superior da seção de conversa"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrar foto do perfil na tela de bloqueio"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecer como balões flutuantes sobre outros apps"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interromper o \"Não perturbe\""</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Ok"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Janela de sobreposição de ampliação"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controles da janela de ampliação"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index b0c815da32b1..9a7f8174bc4b 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controle os balões em qualquer altura"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toque em Gerir para desativar os balões desta app."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"A navegação no sistema foi atualizada. Para efetuar alterações, aceda às Definições."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Aceda às Definições para atualizar a navegação no sistema."</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecem na parte superior da secção de conversas."</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostram a imagem do perfil no ecrã de bloqueio."</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecem como balões flutuantes por cima de apps."</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrompem o modo Não incomodar."</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Janela de sobreposição da ampliação"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controlos da janela de ampliação"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index cd1cd2df6043..0544c50b2aa7 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -710,7 +710,7 @@ <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Chama sua atenção com som ou vibração. As conversas do app <xliff:g id="APP_NAME">%1$s</xliff:g> aparecem em balões por padrão."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Mantém sua atenção com um atalho flutuante para esse conteúdo."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Aparece na parte superior de uma seção de conversa e em forma de balão."</string> - <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Config."</string> + <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Configurações"</string> <string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string> <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nenhum balão recente"</string> <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Os balões recentes e dispensados aparecerão aqui"</string> @@ -999,19 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controle os balões a qualquer momento"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Toque em \"Gerenciar\" para desativar os balões desse app"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ok"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Configurações de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Acesse as configurações para atualizar a navegação no sistema"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Em espera"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecer na parte superior da seção de conversa"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Mostrar foto do perfil na tela de bloqueio"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecer como balões flutuantes sobre outros apps"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interromper o \"Não perturbe\""</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Ok"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Janela de sobreposição de ampliação"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controles da janela de ampliação"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 2ac41df491f1..dc5c682a9985 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -1004,25 +1004,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Controlați oricând baloanele"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Atingeți Gestionați pentru a dezactiva baloanele din această aplicație"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigarea în sistem a fost actualizată. Pentru a face modificări, accesați Setările."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accesați Setările pentru a actualiza navigarea în sistem"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Apar în partea de sus a secțiunii de conversație"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Afișează fotografia de profil pe ecranul de blocare"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Apar ca un balon flotant deasupra aplicațiilor"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Întrerup modul Nu deranja"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Fereastra de suprapunere pentru mărire"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Fereastra de mărire"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Comenzi pentru fereastra de mărire"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Comenzile dispozitivului"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Comenzile dispozitivelor"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Adăugați comenzi pentru dispozitivele conectate"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurați comenzile dispozitivului"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurați comenzile dispozitivelor"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Apăsați butonul de pornire pentru a accesa comenzile"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Alegeți aplicația pentru a adăuga comenzi"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1036,7 +1033,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Au fost șterse toate comenzile"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Lista cu toate comenzile nu a putut fi încărcată."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Altul"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Adăugați la comenzile dispozitivului"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Adăugați la comenzile dispozitivelor"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Adăugați la preferate"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> a sugerat adăugarea acestei comenzi la preferate."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"S-au actualizat comenzile"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 580cd42e9914..00e8e60de139 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -1009,25 +1009,21 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Настройки всплывающих чатов"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Чтобы отключить всплывающие чаты от приложения, нажмите \"Настроить\"."</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"ОК"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>: настройки"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Параметры навигации в системе обновлены. Чтобы изменить их, перейдите в настройки."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Чтобы обновить параметры навигации в системе, перейдите в настройки."</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Переход в режим ожидания"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Показывать в верхней части списка разговоров"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Показывать фото профиля на заблокированном экране"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Показывать как всплывающий чат над приложениями"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Показывать в режиме \"Не беспокоить\""</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"ОК"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Наложение окна увеличения"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Окно увеличения"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Настройки окна увеличения"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Элементы управления"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Виджеты управления устройствами"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Добавьте элементы управления для подключенных устройств"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Настройте элементы управления"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Настройте виджеты управления устройствами"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Чтобы перейти к элементам управления, удерживайте кнопку питания."</string> <string name="controls_providers_title" msgid="6879775889857085056">"Чтобы добавить элементы управления, выберите приложение"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1042,7 +1038,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Все элементы управления удалены"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Не удалось загрузить список элементов управления."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Другое"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Добавьте элементы управления"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Добавьте виджеты управления устройствами"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Добавить в избранное"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"Приложение \"<xliff:g id="APP">%s</xliff:g>\" предлагает добавить этот элемент управления в избранное."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Элементы управления обновлены."</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 77f6ce6bfc37..1fde1e29a5e7 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ඕනෑම වේලාවක බුබුලු පාලනය කරන්න"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"මෙම යෙදුමෙන් බුබුලු ක්රියාවිරහිත කිරීමට කළමනාකරණය කරන්න තට්ටු කරන්න"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"තේරුණා"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"පද්ධති සංචලනය යාවත්කාලීන කළා. වෙනස්කම් සිදු කිරීමට, සැකසීම් වෙත යන්න."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"පද්ධති සංචලනය යාවත්කාලීන කිරීමට සැකසීම් වෙත යන්න"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"පොරොත්තු"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"සංවාද කොටසේ ඉහළ දී පෙන්වන්න"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"පැතිකඩ පින්තූරය අගුලු තිරය මත පෙන්වන්න"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"යෙදුම්වල ඉහළම පාවෙන බුබුලක් ලෙස දිස් වේ"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"බාධා නොකරන්න හට බාධා කරන්න"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"තේරුණා"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"විශාලන උඩැතිරි කවුළුව"</string> <string name="magnification_window_title" msgid="4863914360847258333">"විශාලන කවුළුව"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"විශාලනය කිරීමේ කවුළු පාලන"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 19f4f3d598da..7504f1510476 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -1009,25 +1009,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ovládajte bubliny kedykoľvek"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Klepnutím na Spravovať vypnite bubliny z tejto aplikácie"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Dobre"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigácia v systéme bola aktualizovaná. Ak chcete vykonať zmeny, prejdite do Nastavení."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Prejdite do Nastavení a aktualizujte navigáciu v systéme"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostný režim"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Zobrazovať v hornej sekcii konverzácie"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Zobrazovať profilovú fotku na uzamknutej obrazovke"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Zobrazovať ako plávajúce bubliny nad aplikáciami"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Prerušovať režim bez vyrušení"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Dobre"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Okno prekrytia priblíženia"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Okno priblíženia"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ovládacie prvky okna priblíženia"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Ovládacie prvky zariadenia"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Ovládanie zariadenia"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Pridajte ovládacie prvky pre svoje pripojené zariadenia"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavenie ovládacích prvkov zariadenia"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavenie ovládania zariadenia"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Pridržaním vypínača získate prístup k ovládacím prvkom"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Výberom aplikácie pridajte ovládacie prvky"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1042,7 +1039,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Všetky ovládacie prvky boli odstránené"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Zoznam všetkých ovl. prvkov sa nepodarilo načítať."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Iné"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Pridanie do ovládacích prvkov zariadenia"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Pridanie do ovládania zariadenia"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Pridať do obľúbených"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"Aplikácia <xliff:g id="APP">%s</xliff:g> vám odporučila pridať tento ovládací prvok do obľúbených."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Ovládanie bolo aktualizované"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index e30e042da47f..b4276015aa1f 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -1009,19 +1009,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Upravljanje oblačkov kadar koli"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Dotaknite se »Upravljanje«, da izklopite oblačke iz te aplikacije"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Razumem"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Krmarjenje po sistemu je posodobljeno. Če želite opraviti spremembe, odprite nastavitve."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Če želite posodobiti krmarjenje po sistemu, odprite nastavitve"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravljenosti"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazano na vrhu razdelka s pogovorom"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikaz profilne slike na zaklenjenem zaslonu"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Prikazano kot lebdeč oblaček čez druge aplikacije"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Preglasi način »ne moti«"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"V redu"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Prekrivno povečevalno okno"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Povečevalno okno"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrolniki povečevalnega okna"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 25bc60d6f4ff..ae6089151c4b 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrollo flluskat në çdo moment"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Trokit \"Menaxho\" për të çaktivizuar flluskat nga ky aplikacion"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"E kuptova"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigimi i sistemit u përditësua. Për të bërë ndryshime, shko te \"Cilësimet\"."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Shko te \"Cilësimet\" për të përditësuar navigimin e sistemit"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Në gatishmëri"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Shfaq në krye të seksionit të bisedës"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Shfaq figurën e profilit në ekranin e kyçjes"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Shfaq si flluskë pluskuese mbi aplikacione"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ndërprit \"Mos shqetëso\""</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"E kuptova"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Dritarja e mbivendosjes së zmadhimit"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Dritarja e zmadhimit"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrollet e dritares së zmadhimit"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index d80d774c96ba..c32626c917cb 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -1004,19 +1004,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Контролишите облачиће у било ком тренутку"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Додирните Управљајте да бисте искључили облачиће из ове апликације"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Важи"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигација система је ажурирана. Да бисте унели измене, идите у Подешавања."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Идите у Подешавања да бисте ажурирали навигацију система"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Стање приправности"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Приказују се у врху одељка за конверзације"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Приказују слику профила на закључаном екрану"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Приказују се плутајући облачићи преко апликација"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ометају подешавање Не узнемиравај"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Важи"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Преклопни прозор за увећање"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Прозор за увећање"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Контроле прозора за увећање"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 6218b7b57224..6ef1dfdc3e7d 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Styr bubblor när som helst"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Tryck på Hantera för att stänga av bubblor från den här appen"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Systemnavigeringen har uppdaterats. Öppna inställningarna om du vill ändra något."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Öppna inställningarna och uppdatera systemnavigeringen"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Viloläge"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Visa högst upp bland konversationerna"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Visa profilbild på låsskärmen"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Visa som en flytande bubbla ovanpå appar"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Avbryt Stör ej"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Överlagrat förstoringsfönster"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Förstoringsfönster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Inställningar för förstoringsfönster"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Enhetsinställningar"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Enhetsstyrning"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Lägg till snabbkontroller för anslutna enheter"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurera enhetsinställningar"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurera enhetsstyrning"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Håll strömbrytaren nedtryckt för att få åtkomst till snabbkontrollerna"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Välj en app om du vill lägga till snabbkontroller"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Alla kontroller har tagits bort"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Listan med alla kontroller kunde inte läsas in."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Övrigt"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Lägg till i enhetsinställningar"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Lägg till i enhetsstyrning"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Lägg till i Favoriter"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> föreslår att du lägger till kontrollen i dina favoriter."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Snabbkontroller uppdaterade"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 2cba96a80fdc..01cd04a0f005 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -999,25 +999,21 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Dhibiti viputo wakati wowote"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Gusa Dhibiti ili uzime viputo kwenye programu hii"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Nimeelewa"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"Mipangilio ya <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Umesasisha usogezaji kwenye mfumo. Ili ubadilishe, nenda kwenye Mipangilio."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Nenda kwenye mipangilio ili usasishe usogezaji kwenye mfumo"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Hali tuli"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Onyesha kwenye sehemu ya juu ya mazungumzo"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Onyesha picha ya wasifu kwenye skrini iliyofungwa"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Yataonekana kama kiputo kinachoelea juu ya programu"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Katiza kipengele cha Usinisumbue"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Nimeelewa"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Dirisha la Kuwekelea Linalokuza"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Dirisha la Ukuzaji"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Vidhibiti vya Dirisha la Ukuzaji"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Vidhibiti vya kifaa"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Vidhibiti vya vifaa"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Weka vidhibiti vya vifaa vyako vilivyounganishwa"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Weka mipangilio ya vidhibiti vya kifaa"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Weka mipangilio ya vidhibiti vya vifaa"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Shikilia Kitufe cha kuwasha/kuzima ili ufikie vidhibiti vyako"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Chagua programu ili uweke vidhibiti"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1026,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Umeondoa vidhibiti vyote"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Imeshindwa kupakia orodha ya vidhibiti vyote."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Nyingine"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Weka kwenye vidhibiti vya kifaa"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Weka kwenye vidhibiti vya vifaa"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Ongeza kwenye vipendwa"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> imependekeza kidhibiti hiki ili ukiongeze kwenye vipendwa vyako."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Umesasisha vidhibiti"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 6dab2509d8eb..a0e31d2ceafb 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -1001,19 +1001,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"குமிழ்களை எப்போது வேண்டுமானாலும் கட்டுப்படுத்தலாம்"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"இந்த ஆப்ஸிலிருந்து வரும் குமிழ்களை முடக்க, நிர்வகி என்பதைத் தட்டவும்"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"சரி"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"சிஸ்டம் நேவிகேஷன் மாற்றப்பட்டது. மாற்றங்களைச் செய்ய ‘அமைப்புகளுக்குச்’ செல்லவும்."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"சிஸ்டம் நேவிகேஷனை மாற்ற ’அமைப்புகளுக்குச்’ செல்லவும்"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"இயக்க நேரம்"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"உரையாடல் பிரிவின் மேல் காட்டும்"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"பூட்டுத் திரையின் மேல் சுயவிவரப் படத்தைக் காட்டும்"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ஆப்ஸின் மேல் மிதக்கும் குமிழாகத் தோன்றும்"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தைக் குறுக்கிடும்"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"சரி"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Magnification Overlay Window"</string> <string name="magnification_window_title" msgid="4863914360847258333">"பெரிதாக்கல் சாளரம்"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"பெரிதாக்கல் சாளரக் கட்டுப்பாடுகள்"</string> @@ -1028,10 +1025,8 @@ </plurals> <string name="controls_favorite_default_title" msgid="967742178688938137">"கட்டுப்பாடுகள்"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"பவர் மெனுவில் இருந்து அணுகுவதற்கான கட்டுப்பாடுகளைத் தேர்ந்தெடுக்கலாம்"</string> - <!-- no translation found for controls_favorite_rearrange (5616952398043063519) --> - <skip /> - <!-- no translation found for controls_favorite_removed (5276978408529217272) --> - <skip /> + <string name="controls_favorite_rearrange" msgid="5616952398043063519">"கட்டுப்பாடுகளை மறுவரிசைப்படுத்த அவற்றைப் பிடித்து இழுக்கவும்"</string> + <string name="controls_favorite_removed" msgid="5276978408529217272">"கட்டுப்பாடுகள் அனைத்தும் அகற்றப்பட்டன"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"எல்லா கட்டுப்பாடுகளின் பட்டியலை ஏற்ற முடியவில்லை."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"பிற"</string> <string name="controls_dialog_title" msgid="2343565267424406202">"சாதனக் கட்டுப்பாடுகளில் சேர்த்தல்"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index e365171fe203..e74700923292 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -707,8 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"బబుల్"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"శబ్దం లేదా వైబ్రేషన్ లేకుండా దృష్టి కేంద్రీకరించడానికి మీకు సహాయపడుతుంది."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"శబ్దం లేదా వైబ్రేషన్తో మీరు దృష్టి సారించేలా చేస్తుంది."</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"శబ్దం లేదా వైబ్రేషన్తో మీరు దృష్టి సారించేలా చేస్తుంది. <xliff:g id="APP_NAME">%1$s</xliff:g> నుండి సంభాషణలు డిఫాల్ట్గా బబుల్గా కనిపిస్తాయి."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ఫ్లోటింగ్ షార్ట్కట్తో మీ దృష్టిని ఈ కంటెంట్పై నిలిపి ఉంచుతుంది."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"సంభాషణ విభాగానికి ఎగువున ఉంటుంది, బబుల్లాగా కనిపిస్తుంది."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"సెట్టింగ్లు"</string> @@ -1000,6 +999,8 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"బబుల్స్ను ఎప్పుడైనా నియంత్రించండి"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"ఈ యాప్ నుండి వచ్చే బబుల్స్ను ఆఫ్ చేయడానికి మేనేజ్ బటన్ను ట్యాప్ చేయండి"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"అర్థమైంది"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"సిస్టమ్ నావిగేషన్ అప్డేట్ చేయబడింది. మార్పులు చేయడానికి, సెట్టింగ్లకు వెళ్లండి."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"సిస్టమ్ నావిగేషన్ను అప్డేట్ చేయడానికి సెట్టింగ్లకు వెళ్లండి"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"స్టాండ్బై"</string> @@ -1016,9 +1017,9 @@ <string name="magnification_overlay_title" msgid="6584179429612427958">"మాగ్నిఫికేషన్ ఓవర్లే విండో"</string> <string name="magnification_window_title" msgid="4863914360847258333">"మాగ్నిఫికేషన్ విండో"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"మాగ్నిఫికేషన్ నియంత్రణల విండో"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"పరికర నియంత్రణలు"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"పరికరం నియంత్రణలు"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"మీ కనెక్ట్ అయిన పరికరాలకు నియంత్రణలను జోడించండి"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"పరికర నియంత్రణలను సెటప్ చేయడం"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"పరికరం నియంత్రణలను సెటప్ చేయడం"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"మీ నియంత్రణలను యాక్సెస్ చేయడానికి పవర్ బటన్ను నొక్కి పట్టుకోండి"</string> <string name="controls_providers_title" msgid="6879775889857085056">"నియంత్రణలను యాడ్ చేయడానికి యాప్ను ఎంచుకోండి"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1031,7 +1032,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"అన్ని నియంత్రణలు తీసివేయబడ్డాయి"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"అన్ని నియంత్రణలు గల జాబితాను లోడ్ చేయలేకపోయాము."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"ఇతరం"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"పరికర నియంత్రణలకు జోడించడం"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"పరికరం నియంత్రణలకు జోడించడం"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"ఇష్టమైనవాటికి జోడించు"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"మీ ఇష్టమైనవాటికి జోడించడానికి <xliff:g id="APP">%s</xliff:g> ఈ కంట్రోల్ను సూచించింది."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"నియంత్రణలు అప్డేట్ అయ్యాయి"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 39658710ba2a..bde22a53f15a 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"ควบคุมบับเบิลได้ทุกเมื่อ"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"แตะ \"จัดการ\" เพื่อปิดบับเบิลจากแอปนี้"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"รับทราบ"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"อัปเดตการไปยังส่วนต่างๆ ของระบบแล้ว หากต้องการเปลี่ยนแปลง ให้ไปที่การตั้งค่า"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ไปที่การตั้งค่าเพื่ออัปเดตการไปยังส่วนต่างๆ ของระบบ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"สแตนด์บาย"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"แสดงที่ด้านบนของส่วนการสนทนา"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"แสดงรูปโปรไฟล์บนหน้าจอล็อก"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"แสดงเป็นบับเบิลที่ลอยอยู่เหนือแอป"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"แสดงในโหมดห้ามรบกวน"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"รับทราบ"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"หน้าต่างการขยายที่วางซ้อน"</string> <string name="magnification_window_title" msgid="4863914360847258333">"หน้าต่างการขยาย"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"การควบคุมหน้าต่างการขยาย"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"การควบคุมอุปกรณ์"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"ระบบควบคุมอุปกรณ์"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"เพิ่มตัวควบคุมของอุปกรณ์ที่เชื่อมต่อ"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"ตั้งค่าการควบคุมอุปกรณ์"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"ตั้งค่าระบบควบคุมอุปกรณ์"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"กดปุ่มเปิด/ปิดค้างไว้เพื่อเข้าถึงการควบคุม"</string> <string name="controls_providers_title" msgid="6879775889857085056">"เลือกแอปเพื่อเพิ่มตัวควบคุม"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"นำตัวควบคุมทั้งหมดออกแล้ว"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"โหลดรายการตัวควบคุมทั้งหมดไม่ได้"</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"อื่นๆ"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"เพิ่มไปยังการควบคุมอุปกรณ์"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"เพิ่มไปยังระบบควบคุมอุปกรณ์"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"เพิ่มในรายการโปรด"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> แนะนำให้เพิ่มการควบคุมนี้ในรายการโปรด"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"อัปเดตตัวควบคุมแล้ว"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index ceb9ae14ef2c..cafaaace6fdf 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kontrolin ang mga bubble anumang oras"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"I-tap ang Pamahalaan para i-off ang mga bubble mula sa app na ito"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Na-update na ang pag-navigate ng system. Para gumawa ng mga pagbabago, pumunta sa Mga Setting."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Pumunta sa Mga Setting para i-update ang pag-navigate sa system"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Naka-standby"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Ipakita sa itaas ng seksyon ng pag-uusap"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Ipakita ang larawan sa profile sa lock screen"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Ipakitang floating bubble sa ibabaw ng mga app"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ihinto ang Huwag Istorbohin"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Window ng Overlay sa Pag-magnify"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Window ng Pag-magnify"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Mga Kontrol sa Pag-magnify ng Window"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index d8c822f99e27..c9d53357caf6 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -707,8 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"Baloncuk"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"Ses veya titreşim olmadan odaklanmanıza yardımcı olur."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"Ses veya titreşimle dikkatinizi çeker."</string> - <!-- no translation found for notification_channel_summary_default_with_bubbles (6298026344552480458) --> - <skip /> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Ses veya titreşimle dikkatinizi çeker. <xliff:g id="APP_NAME">%1$s</xliff:g> adlı uygulamadan görüşmeler varsayılan olarak baloncukla gösterilir."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Kayan kısayolla dikkatinizi bu içerik üzerinde tutar."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Görüşme bölümünün üstünde baloncuk olarak gösterilir."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ayarlar"</string> @@ -1000,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Baloncukları istediğiniz zaman kontrol edin"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bu uygulamanın baloncuklarını kapatmak için Yönet\'e dokunun"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Anladım"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Sistemde gezinme yöntemi güncellendi. Değişiklik yapmak için Ayarlar\'a gidin."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Sistemde gezinme yöntemini güncellemek için Ayarlar\'a gidin"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Beklemeye alınıyor"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Görüşme bölümünün üstünde gösterilir"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Kilit ekranında profil resmi gösterilir"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Uygulamaların üzerinde kayan balon olarak görünür"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Rahatsız Etmeyin\'i keser"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Anladım"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Yer Paylaşımlı Büyütme Penceresi"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Büyütme Penceresi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Büyütme Penceresi Kontrolleri"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Cihaz kontrolleri"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Cihaz denetimleri"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Bağlı cihazlarınız için denetimler ekleyin"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Cihaz kontrollerini kur"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Cihaz denetimlerini kur"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Denetimlerinize erişmek için Güç düğmesini basılı tutun"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Denetim eklemek için uygulama seçin"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1031,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Tüm kontroller kaldırıldı"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Tüm kontrollerin listesi yüklenemedi."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Diğer"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Cihaz kontrollerine ekle"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Cihaz denetimlerine ekle"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Favorilere ekle"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g>, bu kontrolü favorilerinize eklemenizi önerdi."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Denetimler güncellendi"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 4c80dbb9690c..00e9d58dd06f 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -1009,25 +1009,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Налаштовуйте спливаючі чати будь-коли"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Натисніть \"Налаштувати\", щоб вимкнути спливаючі чати від цього додатка"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Зрозуміло"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацію в системі оновлено. Щоб внести зміни, перейдіть у налаштування."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перейдіть у налаштування, щоб оновити навігацію в системі"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим очікування"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"З\'являються вгорі розділу розмов"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Показують фото профілю на заблокованому екрані"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"З\'являються як спливаючі чати поверх додатків"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Переривають режим \"Не турбувати\""</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Вікно збільшення з накладанням"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Вікно збільшення"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Елементи керування вікна збільшення"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Елементи керування пристроєм"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Елементи керування пристроями"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Додайте елементи керування для підключених пристроїв"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Налаштувати елементи керування пристроєм"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Налаштувати елементи керування пристроями"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Щоб відкрити елементи керування, утримуйте кнопку живлення"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Виберіть, для якого додатка налаштувати елементи керування"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1042,7 +1039,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Усі елементи керування вилучено"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Не вдалося завантажити список усіх елементів керування."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Інше"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Додати до елементів керування пристроєм"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Додати до елементів керування пристроями"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Додати у вибране"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g> пропонує додати цей елемент керування у вибране."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Елементи керування оновлено"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 6b2ef870376f..6cc8dd3f75c8 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -999,6 +999,8 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"کسی بھی وقت بلبلے کو کنٹرول کریں"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"اس ایپ سے بلبلوں کو آف کرنے کے لیے نظم کریں پر تھپتھپائیں"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"سمجھ آ گئی"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"سسٹم نیویگیشن اپ ڈیٹ کیا گیا۔ تبدیلیاں کرنے کے لیے، ترتیبات پر جائیں۔"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"سسٹم نیویگیشن اپ ڈیٹ کرنے کے لیے ترتیبات پر جائیں"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"اسٹینڈ بائی"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 8fb32e60e2ed..43099f4f060d 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -707,7 +707,7 @@ <string name="notification_bubble_title" msgid="8330481035191903164">"Pufaklar"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"Bildirishnomalar tovush va tebranishsiz keladi."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"Bildirishnomalar tovush va tebranish bilan keladi."</string> - <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Bildirishnomalar tovush va tebranish bilan keladi. <xliff:g id="APP_NAME">%1$s</xliff:g> suhbatlari standart holatda pufaklar shaklida chiqadi."</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Bildirishnomalar tovush va tebranish bilan keladi. <xliff:g id="APP_NAME">%1$s</xliff:g> suhbatlari standart holatda bulutcha shaklida chiqadi."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Bu kontentni ochuvchi erkin yorliq diqqatingizda boʻladi."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Suhbatlar boʻlimining yuqori qismida bulutcha shaklida chiqadi."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Sozlamalar"</string> @@ -999,19 +999,15 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Bulutcha shaklidagi bildirishnomalarni sozlash"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Bu ilova bulutchalarini faolsizlantirish uchun Boshqarish tugmasini bosing"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <string name="bubbles_app_settings" msgid="5779443644062348657">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> sozlamalari"</string> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Tizim navigatsiyasi yangilandi. Buni Sozlamalar orqali oʻzgartirishingiz mumkin."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Tizim navigatsiyasini yangilash uchun Sozlamalarni oching"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Kutib turing"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Suhbatlar qismining tepasida koʻrsatish"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Ekran qulfida profil rasmini koʻrsatish"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Ilovalar ustida bulutchali xabar sifatida chiqadi"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"“Bezovta qilinmasin” rejimida koʻrsatish"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Kattalashtirish oynasining ustidan ochilishi"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Kattalashtirish oynasi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kattalashtirish oynasi sozlamalari"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index e3e525ec1cea..c0996af8051b 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Kiểm soát tùy chọn cài đặt bong bóng trò chuyện bất mọi lúc"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Nhấn vào nút Quản lý để tắt bong bóng trò chuyện từ ứng dụng này"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"OK"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Đã cập nhật chế độ di chuyển trên hệ thống. Để thay đổi, hãy chuyển đến phần Cài đặt."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Chuyển đến phần Cài đặt để cập nhật chế độ di chuyển trên hệ thống"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Chế độ chờ"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Hiển thị ở đầu phần cuộc trò chuyện"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Hiển thị ảnh hồ sơ trên màn hình khóa"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Hiện ở dạng bong bóng nổi ở trên cùng của ứng dụng"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Làm gián đoạn chế độ Không làm phiền"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Cửa sổ lớp phủ phóng to"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Cửa sổ phóng to"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Các tùy chọn điều khiển cửa sổ phóng to"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 9900c95a3e29..fba35b2fe36e 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -100,7 +100,7 @@ <string name="screenrecord_start" msgid="330991441575775004">"开始"</string> <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"正在录制屏幕"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"正在录制屏幕和音频"</string> - <string name="screenrecord_taps_label" msgid="1595690528298857649">"在屏幕上显示轻触位置"</string> + <string name="screenrecord_taps_label" msgid="1595690528298857649">"显示触屏位置"</string> <string name="screenrecord_stop_text" msgid="6549288689506057686">"点按即可停止"</string> <string name="screenrecord_stop_label" msgid="72699670052087989">"停止"</string> <string name="screenrecord_pause_label" msgid="6004054907104549857">"暂停"</string> @@ -348,7 +348,7 @@ <string name="quick_settings_bluetooth_multiple_devices_label" msgid="6595808498429809855">"蓝牙(<xliff:g id="NUMBER">%d</xliff:g> 台设备)"</string> <string name="quick_settings_bluetooth_off_label" msgid="6375098046500790870">"蓝牙:关闭"</string> <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"没有可用的配对设备"</string> - <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"电池电量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> + <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> 的电量"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"音频"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"耳机"</string> <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"输入"</string> @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"随时控制对话泡"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"点按“管理”按钮,可关闭来自此应用的对话泡"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"知道了"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系统导航已更新。要进行更改,请转到“设置”。"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"转到“设置”即可更新系统导航"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待机"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"显示在对话部分顶部"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"在锁定屏幕上显示个人资料照片"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"以悬浮对话泡的形式显示在应用之上"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"中断“勿扰”模式"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"知道了"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"放大叠加窗口"</string> <string name="magnification_window_title" msgid="4863914360847258333">"放大窗口"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"放大窗口控件"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"设备控件"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"设备控制器"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"为您所连接的设备添加控件"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"设置设备控件"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"设置设备控制器"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"按住电源按钮即可访问您的控件"</string> <string name="controls_providers_title" msgid="6879775889857085056">"选择应用以添加控件"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"已移除所有控件"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"无法加载所有控件的列表。"</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"其他"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"添加到设备控件"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"添加到设备控制器"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"添加到收藏夹"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"<xliff:g id="APP">%s</xliff:g>建议将此控件添加到您的收藏夹。"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"控件已更新"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 7002a875d45e..3c0654292d94 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -742,7 +742,7 @@ <string name="notification_conversation_unmute" msgid="2692255619510896710">"發出提醒"</string> <string name="notification_conversation_bubble" msgid="2242180995373949022">"以小視窗顯示"</string> <string name="notification_conversation_unbubble" msgid="6908427185031099868">"移除小視窗"</string> - <string name="notification_conversation_home_screen" msgid="8347136037958438935">"加入主畫面"</string> + <string name="notification_conversation_home_screen" msgid="8347136037958438935">"加到主畫面"</string> <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string> <string name="notification_menu_gear_description" msgid="6429668976593634862">"通知控制項"</string> <string name="notification_menu_snooze_description" msgid="4740133348901973244">"通知延後選項"</string> @@ -999,19 +999,16 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"隨時控制小視窗設定"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"輕按「管理」即可關閉此應用程式的小視窗"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"知道了"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統導覽已更新。如需變更,請前往「設定」。"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"前往「設定」更新系統導覽"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"在對話部分的頂部顯示"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"在上鎖畫面顯示個人檔案相片"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"在應用程式上以浮動小視窗顯示"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"中斷「請勿騷擾」"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"知道了"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"放大重疊視窗"</string> <string name="magnification_window_title" msgid="4863914360847258333">"放大視窗"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"放大視窗控制項"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 170c2f9bcecb..de15aff3adc0 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"你隨時可以控管對話框的各項設定"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"輕觸 [管理] 即可關閉來自這個應用程式的對話框"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"我知道了"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統操作機制已更新。如要進行變更,請前往「設定」。"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"請前往「設定」更新系統操作機制"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"顯示在對話部分的頂端"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"在螢幕鎖定畫面上顯示個人資料相片"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"以浮動對話框形式顯示在應用程式最上層"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"中斷零打擾模式"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"我知道了"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"放大重疊視窗"</string> <string name="magnification_window_title" msgid="4863914360847258333">"放大視窗"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"放大視窗控制項"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"裝置控制項"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"裝置控制"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"新增已連結裝置的控制項"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"設定裝置控制項"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"設定裝置控制"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"按住電源按鈕即可存取控制項"</string> <string name="controls_providers_title" msgid="6879775889857085056">"選擇應用程式以新增控制項"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"所有控制項都已移除"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"無法載入完整的控制項清單。"</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"其他"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"新增至裝置控制項"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"新增至裝置控制"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"新增至常用控制項"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"「<xliff:g id="APP">%s</xliff:g>」建議你將這個控制項新增至常用控制項。"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"已更新控制項"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 127d62df8b0e..e9793422ebde 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -999,25 +999,22 @@ <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Lawula amabhamuza noma nini"</string> <string name="bubbles_user_education_manage" msgid="1391639189507036423">"Thepha okuthi Phatha ukuvala amabhamuza kusuka kulolu hlelo lokusebenza"</string> <string name="bubbles_user_education_got_it" msgid="8282812431953161143">"Ngiyezwa"</string> + <!-- no translation found for bubbles_app_settings (5779443644062348657) --> + <skip /> <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Ukuzulazula kwesistimu kubuyekeziwe. Ukuze wenze ushintsho, hamba kokuthi Izilungiselelo."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Hamba kuzilungiselelo ukuze ubuyekeze ukuzulazula kwesistimu"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ilindile"</string> - <!-- no translation found for priority_onboarding_show_at_top_text (1678400241025513541) --> - <skip /> - <!-- no translation found for priority_onboarding_show_avatar_text (5756291381124091508) --> - <skip /> - <!-- no translation found for priority_onboarding_appear_as_bubble_text (4227039772250263122) --> - <skip /> - <!-- no translation found for priority_onboarding_ignores_dnd_text (2918952762719600529) --> - <skip /> - <!-- no translation found for priority_onboarding_done_button_title (4569550984286506007) --> - <skip /> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Kubonakala esigabeni esiphezulu sengxoxo"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Kubonakala esithombeni sephrofayela esikrinini esikhiyiwe"</string> + <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Kubonakala njengebhamuza elintantayo phezu kwezinhlelo zokusebenza"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Thikameza Ukungaphazamisi"</string> + <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Ngiyezwa"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Iwindi Lembondela Lesikhulisi"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Iwindi Lesikhulisi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Izilawuli Zewindi Lesikhulisi"</string> - <string name="quick_controls_title" msgid="6839108006171302273">"Izilawuli zedivayisi"</string> + <string name="quick_controls_title" msgid="6839108006171302273">"Izilawuli zezinsiza"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Engeza izilawuli zedivayisi yakho exhunyiwe"</string> - <string name="quick_controls_setup_title" msgid="8901436655997849822">"Setha izilawuli zedivayisi"</string> + <string name="quick_controls_setup_title" msgid="8901436655997849822">"Setha izilawuli zezinsiza"</string> <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Bamba inkinobho yamandla ukufinyelela kwizilawuli"</string> <string name="controls_providers_title" msgid="6879775889857085056">"Khetha uhlelo lokusebenza ukwengeza izilawuli"</string> <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380"> @@ -1030,7 +1027,7 @@ <string name="controls_favorite_removed" msgid="5276978408529217272">"Zonke izilawuli zisusiwe"</string> <string name="controls_favorite_load_error" msgid="2533215155804455348">"Uhlu lwazo zonke izilawuli alilayishekanga."</string> <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Okunye"</string> - <string name="controls_dialog_title" msgid="2343565267424406202">"Engeza kuzilawuli zedivayisi"</string> + <string name="controls_dialog_title" msgid="2343565267424406202">"Engeza kuzilawuli zezinsiza"</string> <string name="controls_dialog_ok" msgid="7011816381344485651">"Engeza kuzintandokazi"</string> <string name="controls_dialog_message" msgid="6292099631702047540">"I-<xliff:g id="APP">%s</xliff:g> iphakamise lokhu kulawula ukwengeza kuzintandokazi zakho."</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Izilawuli zibuyekeziwe"</string> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 4482cdac3327..2e217a5e83ea 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -198,6 +198,8 @@ <color name="global_screenshot_button_border">@color/GM2_grey_300</color> <color name="global_screenshot_button_ripple">#1f000000</color> <color name="global_screenshot_button_icon">@color/GM2_blue_500</color> + <color name="global_screenshot_dismiss_background">#FFFFFF</color> + <color name="global_screenshot_dismiss_foreground">@color/GM2_grey_500</color> <!-- GM2 colors --> <color name="GM2_grey_50">#F8F9FA</color> @@ -248,4 +250,7 @@ <color name="control_enabled_thermo_heat_background">@color/GM2_red_200</color> <color name="control_enabled_thermo_cool_background">@color/GM2_blue_200</color> <color name="control_enabled_default_background">@color/GM2_blue_200</color> + + <!-- Docked misalignment message --> + <color name="misalignment_text_color">#F28B82</color> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 179f8b8ea9f4..bad18cf67d98 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -993,8 +993,6 @@ <dimen name="cell_overlay_padding">18dp</dimen> <!-- Global actions power menu --> - <dimen name="global_actions_top_margin">12dp</dimen> - <dimen name="global_actions_panel_width">120dp</dimen> <dimen name="global_actions_padding">12dp</dimen> <dimen name="global_actions_translate">9dp</dimen> @@ -1262,7 +1260,7 @@ <!-- Home Controls activity view detail panel--> <dimen name="controls_activity_view_top_padding">25dp</dimen> <dimen name="controls_activity_view_side_padding">12dp</dimen> - <dimen name="controls_activity_view_top_offset">200dp</dimen> + <dimen name="controls_activity_view_top_offset">100dp</dimen> <dimen name="controls_activity_view_text_size">17sp</dimen> <!-- Home Controls management screens --> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 4ed819e4925b..26ae79081491 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -731,11 +731,6 @@ <item name="android:textSize">@dimen/control_text_size</item> <item name="android:textColor">@color/control_secondary_text</item> </style> - <style name="TextAppearance.ControlDialog"> - <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item> - <item name="android:textSize">@dimen/controls_activity_view_text_size</item> - <item name="android:textColor">@color/control_primary_text</item> - </style> <style name="Control.ListPopupWindow" parent="@*android:style/Widget.DeviceDefault.ListPopupWindow"> <item name="android:overlapAnchor">true</item> diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 4b503785b3f1..4d7eb758f733 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -54,6 +54,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Rect; +import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; import android.service.notification.NotificationListenerService; @@ -176,6 +177,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi private IStatusBarService mBarService; private SysUiState mSysUiState; + // Used to post to main UI thread + private Handler mHandler = new Handler(); + // Used for determining view rect for touch interaction private Rect mTempRect = new Rect(); @@ -805,7 +809,17 @@ public class BubbleController implements ConfigurationController.ConfigurationLi Bubble bubble = mBubbleData.getOrCreateBubble(notif); bubble.setInflateSynchronously(mInflateSynchronously); bubble.inflate( - b -> mBubbleData.notificationEntryUpdated(b, suppressFlyout, showInShade), + b -> { + mBubbleData.notificationEntryUpdated(b, suppressFlyout, showInShade); + if (bubble.getBubbleIntent() == null) { + return; + } + bubble.getBubbleIntent().registerCancelListener(pendingIntent -> { + mHandler.post( + () -> removeBubble(bubble.getEntry(), + BubbleController.DISMISS_INVALID_INTENT)); + }); + }, mContext, mStackView, mBubbleIconFactory); } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java index 0002e862bb41..35406c71a080 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java @@ -128,17 +128,31 @@ public class ExpandedAnimationController */ private boolean mBubbleDraggedOutEnough = false; + /** End action to run when the lead bubble's expansion animation completes. */ + @Nullable private Runnable mLeadBubbleEndAction; + /** - * Animates expanding the bubbles into a row along the top of the screen. + * Animates expanding the bubbles into a row along the top of the screen, optionally running an + * end action when the entire animation completes, and an end action when the lead bubble's + * animation ends. */ - public void expandFromStack(@Nullable Runnable after) { + public void expandFromStack( + @Nullable Runnable after, @Nullable Runnable leadBubbleEndAction) { mAnimatingCollapse = false; mAnimatingExpand = true; mAfterExpand = after; + mLeadBubbleEndAction = leadBubbleEndAction; startOrUpdatePathAnimation(true /* expanding */); } + /** + * Animates expanding the bubbles into a row along the top of the screen. + */ + public void expandFromStack(@Nullable Runnable after) { + expandFromStack(after, null /* leadBubbleEndAction */); + } + /** Animate collapsing the bubbles back to their stacked position. */ public void collapseBackToStack(PointF collapsePoint, Runnable after) { mAnimatingExpand = false; @@ -237,11 +251,17 @@ public class ExpandedAnimationController ? (index * 10) : ((mLayout.getChildCount() - index) * 10); + final boolean isLeadBubble = + (firstBubbleLeads && index == 0) + || (!firstBubbleLeads && index == mLayout.getChildCount() - 1); + animation .followAnimatedTargetAlongPath( path, EXPAND_COLLAPSE_TARGET_ANIM_DURATION /* targetAnimDuration */, - Interpolators.LINEAR /* targetAnimInterpolator */) + Interpolators.LINEAR /* targetAnimInterpolator */, + isLeadBubble ? mLeadBubbleEndAction : null /* endAction */, + () -> mLeadBubbleEndAction = null /* endAction */) .withStartDelay(startDelay) .withStiffness(EXPAND_COLLAPSE_ANIM_STIFFNESS); }).startAll(after); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java index b1bbafc1ed8f..a7d1be1a766a 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java @@ -758,21 +758,34 @@ public class PhysicsAnimationLayout extends FrameLayout { * or {@link #position}, ultimately animating the view's position to the final point on the * given path. * - * Any provided end listeners will be called when the physics-based animations kicked off by - * the moving target have completed - not when the target animation completes. + * @param pathAnimEndActions End actions to run after the animator that moves the target + * along the path ends. The views following the target may still + * be moving. */ public PhysicsPropertyAnimator followAnimatedTargetAlongPath( Path path, int targetAnimDuration, TimeInterpolator targetAnimInterpolator, - Runnable... endActions) { + Runnable... pathAnimEndActions) { mPathAnimator = ObjectAnimator.ofFloat( this, mCurrentPointOnPathXProperty, mCurrentPointOnPathYProperty, path); + + if (pathAnimEndActions != null) { + mPathAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + for (Runnable action : pathAnimEndActions) { + if (action != null) { + action.run(); + } + } + } + }); + } + mPathAnimator.setDuration(targetAnimDuration); mPathAnimator.setInterpolator(targetAnimInterpolator); - mPositionEndActions = endActions; - // Remove translation related values since we're going to ignore them and follow the // path instead. clearTranslationValues(); diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt index 7e8fec716b1f..e84f439c1fe2 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt @@ -31,6 +31,7 @@ import com.android.internal.annotations.VisibleForTesting import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.util.concurrency.DelayableExecutor import dagger.Lazy +import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Inject import javax.inject.Singleton @@ -284,13 +285,19 @@ open class ControlsBindingControllerImpl @Inject constructor( val requestLimit: Long ) : IControlsSubscriber.Stub() { val loadedControls = ArrayList<Control>() - private var isTerminated = false + private var isTerminated = AtomicBoolean(false) private var _loadCancelInternal: (() -> Unit)? = null private lateinit var subscription: IControlsSubscription + /** + * Potentially cancel a subscriber. The subscriber may also have terminated, in which case + * the request is ignored. + */ fun loadCancel() = Runnable { - Log.d(TAG, "Cancel load requested") - _loadCancelInternal?.invoke() + _loadCancelInternal?.let { + Log.d(TAG, "Canceling loadSubscribtion") + it.invoke() + } } override fun onSubscribe(token: IBinder, subs: IControlsSubscription) { @@ -301,7 +308,7 @@ open class ControlsBindingControllerImpl @Inject constructor( override fun onNext(token: IBinder, c: Control) { backgroundExecutor.execute { - if (isTerminated) return@execute + if (isTerminated.get()) return@execute loadedControls.add(c) @@ -325,13 +332,15 @@ open class ControlsBindingControllerImpl @Inject constructor( } private fun maybeTerminateAndRun(postTerminateFn: Runnable) { - if (isTerminated) return + if (isTerminated.get()) return - isTerminated = true _loadCancelInternal = {} currentProvider?.cancelLoadTimeout() - backgroundExecutor.execute(postTerminateFn) + backgroundExecutor.execute { + isTerminated.compareAndSet(false, true) + postTerminateFn.run() + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt index 79a5b0a1ce52..bc97c10756fd 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt @@ -52,19 +52,17 @@ interface ControlsController : UserAwareController { * Load all available [Control] for a given service. * * @param componentName the [ComponentName] of the [ControlsProviderService] to load from - * @param dataCallback a callback in which to retrieve the result. + * @param dataCallback a callback in which to retrieve the result + * @param cancelWrapper a callback to receive a [Runnable] that can be run to cancel the + * request */ fun loadForComponent( componentName: ComponentName, - dataCallback: Consumer<LoadData> + dataCallback: Consumer<LoadData>, + cancelWrapper: Consumer<Runnable> ) /** - * Cancels a pending load call - */ - fun cancelLoad() - - /** * Request to subscribe for favorited controls per structure * * @param structureInfo structure to limit the subscription to diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt index 5626a5de2e3c..8e88756b16fd 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt @@ -77,8 +77,6 @@ class ControlsControllerImpl @Inject constructor ( private var userChanging: Boolean = true - private var loadCanceller: Runnable? = null - private var seedingInProgress = false private val seedingCallbacks = mutableListOf<Consumer<Boolean>>() @@ -276,28 +274,29 @@ class ControlsControllerImpl @Inject constructor ( override fun loadForComponent( componentName: ComponentName, - dataCallback: Consumer<ControlsController.LoadData> + dataCallback: Consumer<ControlsController.LoadData>, + cancelWrapper: Consumer<Runnable> ) { if (!confirmAvailability()) { if (userChanging) { // Try again later, userChanging should not last forever. If so, we have bigger // problems. This will return a runnable that allows to cancel the delayed version, // it will not be able to cancel the load if - loadCanceller = executor.executeDelayed( - { loadForComponent(componentName, dataCallback) }, - USER_CHANGE_RETRY_DELAY, - TimeUnit.MILLISECONDS + executor.executeDelayed( + { loadForComponent(componentName, dataCallback, cancelWrapper) }, + USER_CHANGE_RETRY_DELAY, + TimeUnit.MILLISECONDS ) - } else { - dataCallback.accept(createLoadDataObject(emptyList(), emptyList(), true)) } - return + + dataCallback.accept(createLoadDataObject(emptyList(), emptyList(), true)) } - loadCanceller = bindingController.bindAndLoad( + + cancelWrapper.accept( + bindingController.bindAndLoad( componentName, object : ControlsBindingController.LoadCallback { override fun accept(controls: List<Control>) { - loadCanceller = null executor.execute { val favoritesForComponentKeys = Favorites .getControlsForComponent(componentName).map { it.controlId } @@ -333,7 +332,6 @@ class ControlsControllerImpl @Inject constructor ( } override fun error(message: String) { - loadCanceller = null executor.execute { val controls = Favorites.getStructuresForComponent(componentName) .flatMap { st -> @@ -348,6 +346,7 @@ class ControlsControllerImpl @Inject constructor ( } } } + ) ) } @@ -432,12 +431,6 @@ class ControlsControllerImpl @Inject constructor ( seedingCallbacks.clear() } - override fun cancelLoad() { - loadCanceller?.let { - executor.execute(it) - } - } - private fun createRemovedStatus( componentName: ComponentName, controlInfo: ControlInfo, diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt index 273e47c1c094..640c90d2ba59 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt @@ -32,6 +32,7 @@ import com.android.systemui.R import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.controls.controller.ControlsControllerImpl import com.android.systemui.controls.controller.StructureInfo +import com.android.systemui.globalactions.GlobalActionsComponent import com.android.systemui.settings.CurrentUserTracker import com.android.systemui.util.LifecycleActivity import javax.inject.Inject @@ -41,7 +42,8 @@ import javax.inject.Inject */ class ControlsEditingActivity @Inject constructor( private val controller: ControlsControllerImpl, - broadcastDispatcher: BroadcastDispatcher + broadcastDispatcher: BroadcastDispatcher, + private val globalActionsComponent: GlobalActionsComponent ) : LifecycleActivity() { companion object { @@ -86,12 +88,20 @@ class ControlsEditingActivity @Inject constructor( bindViews() bindButtons() + } + override fun onStart() { + super.onStart() setUpList() currentUserTracker.startTracking() } + override fun onStop() { + super.onStop() + currentUserTracker.stopTracking() + } + private fun bindViews() { setContentView(R.layout.controls_management) @@ -129,12 +139,21 @@ class ControlsEditingActivity @Inject constructor( } } + val rootView = requireViewById<ViewGroup>(R.id.controls_management_root) saveButton = requireViewById<Button>(R.id.done).apply { isEnabled = false setText(R.string.save) setOnClickListener { saveFavorites() - finishAffinity() + ControlsAnimations.exitAnimation( + rootView, + object : Runnable { + override fun run() { + finish() + } + } + ).start() + globalActionsComponent.handleShowGlobalActionsMenu() } } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt index 4a3470507010..9a2ccb52132b 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt @@ -20,7 +20,6 @@ import android.app.ActivityOptions import android.content.ComponentName import android.content.Intent import android.content.res.Configuration -import android.graphics.drawable.Drawable import android.os.Bundle import android.text.TextUtils import android.view.Gravity @@ -29,7 +28,6 @@ import android.view.ViewGroup import android.view.ViewStub import android.widget.Button import android.widget.FrameLayout -import android.widget.ImageView import android.widget.TextView import androidx.viewpager2.widget.ViewPager2 import com.android.systemui.Prefs @@ -40,6 +38,7 @@ import com.android.systemui.controls.TooltipManager import com.android.systemui.controls.controller.ControlsControllerImpl import com.android.systemui.controls.controller.StructureInfo import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.globalactions.GlobalActionsComponent import com.android.systemui.settings.CurrentUserTracker import com.android.systemui.util.LifecycleActivity import java.text.Collator @@ -51,7 +50,8 @@ class ControlsFavoritingActivity @Inject constructor( @Main private val executor: Executor, private val controller: ControlsControllerImpl, private val listingController: ControlsListingController, - broadcastDispatcher: BroadcastDispatcher + broadcastDispatcher: BroadcastDispatcher, + private val globalActionsComponent: GlobalActionsComponent ) : LifecycleActivity() { companion object { @@ -74,14 +74,15 @@ class ControlsFavoritingActivity @Inject constructor( private lateinit var structurePager: ViewPager2 private lateinit var statusText: TextView private lateinit var titleView: TextView - private lateinit var iconView: ImageView - private lateinit var iconFrame: View private lateinit var pageIndicator: ManagementPageIndicator private var mTooltipManager: TooltipManager? = null private lateinit var doneButton: View + private lateinit var otherAppsButton: View private var listOfStructures = emptyList<StructureContainer>() private lateinit var comparator: Comparator<StructureContainer> + private var cancelLoadRunnable: Runnable? = null + private var isPagerLoaded = false private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) { private val startingUser = controller.currentUserId @@ -95,17 +96,10 @@ class ControlsFavoritingActivity @Inject constructor( } private val listingCallback = object : ControlsListingController.ControlsListingCallback { - private var icon: Drawable? = null override fun onServicesUpdated(serviceInfos: List<ControlsServiceInfo>) { - val newIcon = serviceInfos.firstOrNull { it.componentName == component }?.loadIcon() - if (icon == newIcon) return - icon = newIcon - executor.execute { - if (icon != null) { - iconView.setImageDrawable(icon) - } - iconFrame.visibility = if (icon != null) View.VISIBLE else View.GONE + if (serviceInfos.size > 1) { + otherAppsButton.visibility = View.VISIBLE } } } @@ -124,14 +118,6 @@ class ControlsFavoritingActivity @Inject constructor( component = intent.getParcelableExtra<ComponentName>(Intent.EXTRA_COMPONENT_NAME) bindViews() - - setUpPager() - - loadControls() - - listingController.addCallback(listingCallback) - - currentUserTracker.startTracking() } private val controlsModelCallback = object : ControlsModel.ControlsModelCallback { @@ -180,7 +166,7 @@ class ControlsFavoritingActivity @Inject constructor( ControlsAnimations.enterAnimation(pageIndicator).start() ControlsAnimations.enterAnimation(structurePager).start() } - }) + }, Consumer { runnable -> cancelLoadRunnable = runnable }) } } @@ -275,8 +261,6 @@ class ControlsFavoritingActivity @Inject constructor( } requireViewById<TextView>(R.id.subtitle).text = resources.getText(R.string.controls_favorite_subtitle) - iconView = requireViewById(com.android.internal.R.id.icon) - iconFrame = requireViewById(R.id.icon_frame) structurePager = requireViewById<ViewPager2>(R.id.structure_pager) structurePager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { @@ -288,8 +272,7 @@ class ControlsFavoritingActivity @Inject constructor( } private fun bindButtons() { - requireViewById<Button>(R.id.other_apps).apply { - visibility = View.VISIBLE + otherAppsButton = requireViewById<Button>(R.id.other_apps).apply { setOnClickListener { val i = Intent() i.setComponent( @@ -299,6 +282,7 @@ class ControlsFavoritingActivity @Inject constructor( } } + val rootView = requireViewById<ViewGroup>(R.id.controls_management_root) doneButton = requireViewById<Button>(R.id.done).apply { isEnabled = false setOnClickListener { @@ -309,7 +293,16 @@ class ControlsFavoritingActivity @Inject constructor( StructureInfo(component!!, it.structureName, favoritesForStorage) ) } - finishAffinity() + + ControlsAnimations.exitAnimation( + rootView, + object : Runnable { + override fun run() { + finish() + } + } + ).start() + globalActionsComponent.handleShowGlobalActionsMenu() } } } @@ -319,15 +312,39 @@ class ControlsFavoritingActivity @Inject constructor( mTooltipManager?.hide(false) } + override fun onStart() { + super.onStart() + + listingController.addCallback(listingCallback) + currentUserTracker.startTracking() + } + + override fun onResume() { + super.onResume() + + // only do once, to make sure that any user changes do not get replaces if resume is called + // more than once + if (!isPagerLoaded) { + setUpPager() + loadControls() + isPagerLoaded = true + } + } + + override fun onStop() { + super.onStop() + + listingController.removeCallback(listingCallback) + currentUserTracker.stopTracking() + } + override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) mTooltipManager?.hide(false) } override fun onDestroy() { - currentUserTracker.stopTracking() - listingController.removeCallback(listingCallback) - controller.cancelLoad() + cancelLoadRunnable?.run() super.onDestroy() } diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt index 59a8b32a10e7..00448544d691 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt @@ -21,6 +21,7 @@ import android.content.ComponentName import android.content.Intent import android.os.Bundle import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import android.view.ViewStub import android.widget.Button @@ -84,8 +85,27 @@ class ControlsProviderSelectorActivity @Inject constructor( } recyclerView = requireViewById(R.id.list) - recyclerView.alpha = 0.0f recyclerView.layoutManager = LinearLayoutManager(applicationContext) + + requireViewById<TextView>(R.id.title).apply { + text = resources.getText(R.string.controls_providers_title) + } + + requireViewById<Button>(R.id.other_apps).apply { + visibility = View.VISIBLE + setText(com.android.internal.R.string.cancel) + setOnClickListener { + this@ControlsProviderSelectorActivity.finishAffinity() + } + } + requireViewById<View>(R.id.done).visibility = View.GONE + } + + override fun onStart() { + super.onStart() + currentUserTracker.startTracking() + + recyclerView.alpha = 0.0f recyclerView.adapter = AppAdapter( backExecutor, executor, @@ -105,16 +125,11 @@ class ControlsProviderSelectorActivity @Inject constructor( } }) } + } - requireViewById<TextView>(R.id.title).apply { - text = resources.getText(R.string.controls_providers_title) - } - - requireViewById<Button>(R.id.done).setOnClickListener { - this@ControlsProviderSelectorActivity.finishAffinity() - } - - currentUserTracker.startTracking() + override fun onStop() { + super.onStop() + currentUserTracker.stopTracking() } /** diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt index b3c6cab2adff..0af29bec04b3 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt @@ -17,14 +17,11 @@ package com.android.systemui.controls.ui import android.app.Dialog -import android.app.PendingIntent import android.content.Intent import android.service.controls.Control import android.service.controls.actions.BooleanAction import android.service.controls.actions.CommandAction -import android.util.Log import android.view.HapticFeedbackConstants -import com.android.systemui.R import com.android.systemui.controls.controller.ControlsController object ControlActionCoordinator { @@ -51,23 +48,14 @@ object ControlActionCoordinator { } /** - * Allow apps to specify whether they would like to appear in a detail panel or within - * the full activity by setting the {@link Control#EXTRA_USE_PANEL} flag. In order for - * activities to determine how they are being launched, they should inspect the - * {@link Control#EXTRA_USE_PANEL} flag for a value of true. + * All long presses will be shown in a 3/4 height bottomsheet panel, in order for the user to + * retain context with their favorited controls in the power menu. */ fun longPress(cvh: ControlViewHolder) { // Long press snould only be called when there is valid control state, otherwise ignore cvh.cws.control?.let { - try { - it.getAppIntent().send() - cvh.layout.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) - cvh.context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) - } catch (e: PendingIntent.CanceledException) { - Log.e(ControlsUiController.TAG, "Error sending pending intent", e) - cvh.setTransientStatus( - cvh.context.resources.getString(R.string.controls_error_failed)) - } + cvh.layout.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) + showDialog(cvh, it.getAppIntent().getIntent()) } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt index 61a323d0b9a8..5be2f221ebcb 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt @@ -52,8 +52,7 @@ class ControlViewHolder( val layout: ViewGroup, val controlsController: ControlsController, val uiExecutor: DelayableExecutor, - val bgExecutor: DelayableExecutor, - val usePanels: Boolean + val bgExecutor: DelayableExecutor ) { companion object { @@ -159,8 +158,7 @@ class ControlViewHolder( controlsController.action(cws.componentName, cws.ci, action) } - fun usePanel(): Boolean = - usePanels && deviceType in ControlViewHolder.FORCE_PANEL_DEVICES + fun usePanel(): Boolean = deviceType in ControlViewHolder.FORCE_PANEL_DEVICES private fun findBehavior( status: Int, @@ -186,22 +184,36 @@ class ControlViewHolder( val fg = context.resources.getColorStateList(ri.foreground, context.theme) val bg = context.resources.getColor(R.color.control_default_background, context.theme) val dimAlpha = if (dimmed) dimmedAlpha else 1f - var (clip, newAlpha) = if (enabled) { - listOf(ri.enabledBackground, ALPHA_ENABLED) + var (newClipColor, newAlpha) = if (enabled) { + // allow color overrides for the enabled state only + val color = cws.control?.getCustomColor()?.let { + val state = intArrayOf(android.R.attr.state_enabled) + it.getColorForState(state, it.getDefaultColor()) + } ?: context.resources.getColor(ri.enabledBackground, context.theme) + listOf(color, ALPHA_ENABLED) } else { - listOf(R.color.control_default_background, ALPHA_DISABLED) + listOf( + context.resources.getColor(R.color.control_default_background, context.theme), + ALPHA_DISABLED + ) } status.setTextColor(fg) - icon.setImageDrawable(ri.icon) - // do not color app icons - if (deviceType != DeviceTypes.TYPE_ROUTINE) { - icon.imageTintList = fg + cws.control?.getCustomIcon()?.let { + // do not tint custom icons, assume the intended icon color is correct + icon.imageTintList = null + icon.setImageIcon(it) + } ?: run { + icon.setImageDrawable(ri.icon) + + // do not color app icons + if (deviceType != DeviceTypes.TYPE_ROUTINE) { + icon.imageTintList = fg + } } (clipLayer.getDrawable() as GradientDrawable).apply { - val newClipColor = context.resources.getColor(clip, context.theme) val newBaseColor = if (behavior is ToggleRangeBehavior) { ColorUtils.blendARGB(bg, newClipColor, toggleBackgroundIntensity) } else { diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index cfd8df059567..bf0f1c85249c 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -30,7 +30,6 @@ import android.content.res.Configuration import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable import android.os.Process -import android.provider.Settings import android.service.controls.Control import android.service.controls.actions.ControlAction import android.util.Log @@ -84,7 +83,6 @@ class ControlsUiControllerImpl @Inject constructor ( private const val PREF_COMPONENT = "controls_component" private const val PREF_STRUCTURE = "controls_structure" - private const val USE_PANELS = "systemui.controls_use_panel" private const val FADE_IN_MILLIS = 200L private val EMPTY_COMPONENT = ComponentName("", "") @@ -441,9 +439,6 @@ class ControlsUiControllerImpl @Inject constructor ( val maxColumns = findMaxColumns() - // use flag only temporarily for testing - val usePanels = Settings.Secure.getInt(context.contentResolver, USE_PANELS, 0) == 1 - val listView = parent.requireViewById(R.id.global_actions_controls_list) as ViewGroup var lastRow: ViewGroup = createRow(inflater, listView) selectedStructure.controls.forEach { @@ -457,8 +452,7 @@ class ControlsUiControllerImpl @Inject constructor ( baseLayout, controlsController.get(), uiExecutor, - bgExecutor, - usePanels + bgExecutor ) val key = ControlKey(selectedStructure.componentName, it.controlId) cvh.bindData(controlsById.getValue(key)) diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt index 15c41a2005a6..65ed9678c63e 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt @@ -24,9 +24,9 @@ import android.provider.Settings import android.view.View import android.view.ViewGroup import android.view.WindowInsets +import android.view.WindowInsets.Type import android.view.WindowManager import android.widget.ImageView -import android.widget.TextView import com.android.systemui.R @@ -45,7 +45,7 @@ class DetailDialog( private const val PANEL_TOP_OFFSET = "systemui.controls_panel_top_offset" } - lateinit var activityView: ActivityView + var activityView = ActivityView(context, null, 0, false) val stateCallback: ActivityView.StateCallback = object : ActivityView.StateCallback() { override fun onActivityViewReady(view: ActivityView) { @@ -67,10 +67,8 @@ class DetailDialog( init { window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY) - setContentView(R.layout.controls_detail_dialog) - activityView = ActivityView(context, null, 0, false) requireViewById<ViewGroup>(R.id.controls_activity_view).apply { addView(activityView) } @@ -79,14 +77,6 @@ class DetailDialog( setOnClickListener { _: View -> dismiss() } } - requireViewById<TextView>(R.id.title).apply { - setText(cvh.title.text) - } - - requireViewById<TextView>(R.id.subtitle).apply { - setText(cvh.subtitle.text) - } - requireViewById<ImageView>(R.id.control_detail_open_in_app).apply { setOnClickListener { v: View -> dismiss() @@ -97,15 +87,15 @@ class DetailDialog( // consume all insets to achieve slide under effect window.getDecorView().setOnApplyWindowInsetsListener { - v: View, insets: WindowInsets -> + _: View, insets: WindowInsets -> activityView.apply { val l = getPaddingLeft() val t = getPaddingTop() val r = getPaddingRight() - setPadding(l, t, r, insets.getSystemWindowInsets().bottom) + setPadding(l, t, r, insets.getInsets(Type.systemBars()).bottom) } - insets.consumeSystemWindowInsets() + WindowInsets.CONSUMED } requireViewById<ViewGroup>(R.id.control_detail_root).apply { @@ -118,6 +108,9 @@ class DetailDialog( val lp = getLayoutParams() as ViewGroup.MarginLayoutParams lp.topMargin = offsetInPx setLayoutParams(lp) + + setOnClickListener { dismiss() } + (getParent() as View).setOnClickListener { dismiss() } } } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java index 88f96a8b19fe..8c572fe8f842 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java @@ -24,7 +24,6 @@ import android.content.Context; import androidx.annotation.Nullable; import com.android.keyguard.KeyguardViewController; -import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManagerImpl; import com.android.systemui.plugins.qs.QSFactory; @@ -34,7 +33,6 @@ import com.android.systemui.power.EnhancedEstimatesImpl; import com.android.systemui.qs.tileimpl.QSFactoryImpl; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsImplementation; -import com.android.systemui.settings.CurrentUserContextTracker; import com.android.systemui.stackdivider.DividerModule; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationLockscreenUserManager; @@ -138,15 +136,4 @@ public abstract class SystemUIDefaultModule { @Binds abstract KeyguardViewController bindKeyguardViewController( StatusBarKeyguardViewManager statusBarKeyguardViewManager); - - @Singleton - @Provides - static CurrentUserContextTracker provideCurrentUserContextTracker( - Context context, - BroadcastDispatcher broadcastDispatcher) { - CurrentUserContextTracker tracker = - new CurrentUserContextTracker(context, broadcastDispatcher); - tracker.initialize(); - return tracker; - } } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 2e9ce1200c85..90cd13fd1330 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -29,6 +29,7 @@ import com.android.systemui.log.dagger.LogModule; import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.Recents; +import com.android.systemui.settings.dagger.SettingsModule; import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder; @@ -61,6 +62,7 @@ import dagger.Provides; ConcurrencyModule.class, LogModule.class, PeopleHubModule.class, + SettingsModule.class }, subcomponents = {StatusBarComponent.class, NotificationRowComponent.class, diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index b211ccc28803..eb80a2bc73bb 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -129,7 +129,6 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.EmergencyDialerConstants; import com.android.systemui.util.RingerModeTracker; import com.android.systemui.util.leak.RotationUtils; -import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolator; import java.util.ArrayList; import java.util.List; @@ -1899,6 +1898,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private ControlsUiController mControlsUiController; private ViewGroup mControlsView; + private ViewGroup mContainer; ActionsDialog(Context context, MyAdapter adapter, MyOverflowAdapter overflowAdapter, GlobalActionsPanelPlugin.PanelViewController plugin, @@ -2039,7 +2039,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, fixNavBarClipping(); mControlsView = findViewById(com.android.systemui.R.id.global_actions_controls); mGlobalActionsLayout = findViewById(com.android.systemui.R.id.global_actions_view); - mGlobalActionsLayout.setOutsideTouchListener(view -> dismiss()); mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() { @Override public boolean dispatchPopulateAccessibilityEvent( @@ -2051,6 +2050,11 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, }); mGlobalActionsLayout.setRotationListener(this::onRotate); mGlobalActionsLayout.setAdapter(mAdapter); + mContainer = findViewById(com.android.systemui.R.id.global_actions_container); + // Some legacy dialog layouts don't have the outer container + if (mContainer == null) { + mContainer = mGlobalActionsLayout; + } mOverflowPopup = createPowerOverflowPopup(); @@ -2073,15 +2077,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } } - View globalActionsParent = (View) mGlobalActionsLayout.getParent(); - globalActionsParent.setOnClickListener(v -> dismiss()); - - // add fall-through dismiss handling to root view - View rootView = findViewById(com.android.systemui.R.id.global_actions_grid_root); - if (rootView != null) { - rootView.setOnClickListener(v -> dismiss()); - } - if (shouldUsePanel()) { initializePanel(); } @@ -2177,10 +2172,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mHadTopUi = mNotificationShadeWindowController.getForceHasTopUi(); mNotificationShadeWindowController.setForceHasTopUi(true); mBackgroundDrawable.setAlpha(0); - mGlobalActionsLayout.setTranslationX(mGlobalActionsLayout.getAnimationOffsetX()); - mGlobalActionsLayout.setTranslationY(mGlobalActionsLayout.getAnimationOffsetY()); - mGlobalActionsLayout.setAlpha(0); - mGlobalActionsLayout.animate() + mContainer.setTranslationX(mGlobalActionsLayout.getAnimationOffsetX()); + mContainer.setTranslationY(mGlobalActionsLayout.getAnimationOffsetY()); + mContainer.setAlpha(0); + mContainer.animate() .alpha(1) .translationX(0) .translationY(0) @@ -2212,16 +2207,16 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, @Override public void dismiss() { dismissWithAnimation(() -> { - mGlobalActionsLayout.setTranslationX(0); - mGlobalActionsLayout.setTranslationY(0); - mGlobalActionsLayout.setAlpha(1); - mGlobalActionsLayout.animate() + mContainer.setTranslationX(0); + mContainer.setTranslationY(0); + mContainer.setAlpha(1); + mContainer.animate() .alpha(0) .translationX(mGlobalActionsLayout.getAnimationOffsetX()) .translationY(mGlobalActionsLayout.getAnimationOffsetY()) - .setDuration(550) + .setDuration(450) .withEndAction(this::completeDismiss) - .setInterpolator(new LogAccelerateInterpolator()) + .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) .setUpdateListener(animation -> { float animatedValue = 1f - animation.getAnimatedFraction(); int alpha = (int) (animatedValue * mScrimAlpha * 255); @@ -2235,7 +2230,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private void dismissForControlsActivity() { dismissWithAnimation(() -> { - ViewGroup root = (ViewGroup) mGlobalActionsLayout.getRootView(); + ViewGroup root = (ViewGroup) mGlobalActionsLayout.getParent(); ControlsAnimations.exitAnimation(root, this::completeDismiss).start(); }); } diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index 14e3e9390825..123cf78d74f8 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -61,6 +61,18 @@ public class LogModule { return buffer; } + /** Provides a logging buffer for all logs related to the data layer of notifications. */ + @Provides + @Singleton + @NotifInteractionLog + public static LogBuffer provideNotifInteractionLogBuffer( + LogcatEchoTracker echoTracker, + DumpManager dumpManager) { + LogBuffer buffer = new LogBuffer("NotifInteractionLog", 50, 10, echoTracker); + buffer.attach(dumpManager); + return buffer; + } + /** Provides a logging buffer for all logs related to Quick Settings. */ @Provides @Singleton diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/NotifInteractionLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NotifInteractionLog.java new file mode 100644 index 000000000000..20fc6ff445a6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NotifInteractionLog.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log.dagger; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.android.systemui.log.LogBuffer; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Qualifier; + +/** + * A {@link LogBuffer} for messages related to the user interacting with notifications (e.g. + * clicking on them). + */ +@Qualifier +@Documented +@Retention(RUNTIME) +public @interface NotifInteractionLog { +} diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 233d24b17d44..683c7934908b 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -57,7 +57,6 @@ import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; import com.android.settingslib.media.MediaOutputSliceConstants; import com.android.settingslib.widget.AdaptiveIcon; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.qs.QSMediaBrowser; @@ -75,6 +74,7 @@ public class MediaControlPanel { @Nullable private final LocalMediaManager mLocalMediaManager; private final Executor mForegroundExecutor; protected final Executor mBackgroundExecutor; + private final ActivityStarter mActivityStarter; private Context mContext; protected LinearLayout mMediaNotifView; @@ -178,10 +178,12 @@ public class MediaControlPanel { * @param actionIds resource IDs for action buttons in the layout * @param foregroundExecutor foreground executor * @param backgroundExecutor background executor, used for processing artwork + * @param activityStarter activity starter */ public MediaControlPanel(Context context, ViewGroup parent, @Nullable LocalMediaManager routeManager, @LayoutRes int layoutId, int[] actionIds, - Executor foregroundExecutor, Executor backgroundExecutor) { + Executor foregroundExecutor, Executor backgroundExecutor, + ActivityStarter activityStarter) { mContext = context; LayoutInflater inflater = LayoutInflater.from(mContext); mMediaNotifView = (LinearLayout) inflater.inflate(layoutId, parent, false); @@ -195,6 +197,7 @@ public class MediaControlPanel { mActionIds = actionIds; mForegroundExecutor = foregroundExecutor; mBackgroundExecutor = backgroundExecutor; + mActivityStarter = activityStarter; } /** @@ -267,13 +270,7 @@ public class MediaControlPanel { // Click action if (contentIntent != null) { mMediaNotifView.setOnClickListener(v -> { - try { - contentIntent.send(); - // Also close shade - mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); - } catch (PendingIntent.CanceledException e) { - Log.e(TAG, "Pending intent was canceled", e); - } + mActivityStarter.postStartActivityDismissingKeyguard(contentIntent); }); } @@ -287,7 +284,6 @@ public class MediaControlPanel { if (mSeamless != null && mLocalMediaManager != null) { mSeamless.setVisibility(View.VISIBLE); updateDevice(mLocalMediaManager.getCurrentConnectedDevice()); - ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class); mSeamless.setOnClickListener(v -> { final Intent intent = new Intent() .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT) @@ -632,8 +628,10 @@ public class MediaControlPanel { public void onError() { Log.d(TAG, "Cannot resume with " + componentName); mServiceComponent = null; - clearControls(); - // remove + if (!hasMediaSession()) { + // If it's not active and we can't resume, remove + removePlayer(); + } } }, componentName); diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java index dba43430b490..f322489b8dc2 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java @@ -53,16 +53,23 @@ public class PipAnimationController { public static final int TRANSITION_DIRECTION_SAME = 1; public static final int TRANSITION_DIRECTION_TO_PIP = 2; public static final int TRANSITION_DIRECTION_TO_FULLSCREEN = 3; + public static final int TRANSITION_DIRECTION_TO_SPLIT_SCREEN = 4; @IntDef(prefix = { "TRANSITION_DIRECTION_" }, value = { TRANSITION_DIRECTION_NONE, TRANSITION_DIRECTION_SAME, TRANSITION_DIRECTION_TO_PIP, - TRANSITION_DIRECTION_TO_FULLSCREEN + TRANSITION_DIRECTION_TO_FULLSCREEN, + TRANSITION_DIRECTION_TO_SPLIT_SCREEN }) @Retention(RetentionPolicy.SOURCE) public @interface TransitionDirection {} + public static boolean isOutPipDirection(@TransitionDirection int direction) { + return direction == TRANSITION_DIRECTION_TO_FULLSCREEN + || direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN; + } + private final Interpolator mFastOutSlowInInterpolator; private final PipSurfaceTransactionHelper mSurfaceTransactionHelper; @@ -253,14 +260,13 @@ public class PipAnimationController { } boolean shouldApplyCornerRadius() { - return mTransitionDirection != TRANSITION_DIRECTION_TO_FULLSCREEN; + return !isOutPipDirection(mTransitionDirection); } boolean inScaleTransition() { if (mAnimationType != ANIM_TYPE_BOUNDS) return false; final int direction = getTransitionDirection(); - return direction != TRANSITION_DIRECTION_TO_FULLSCREEN - && direction != TRANSITION_DIRECTION_TO_PIP; + return !isOutPipDirection(direction) && direction != TRANSITION_DIRECTION_TO_PIP; } /** diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 0125153542c1..9eae3ca232ff 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -16,7 +16,6 @@ package com.android.systemui.pip; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_ALPHA; @@ -25,6 +24,8 @@ import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTI import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_SAME; import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN; import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP; +import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_SPLIT_SCREEN; +import static com.android.systemui.pip.PipAnimationController.isOutPipDirection; import android.annotation.NonNull; import android.annotation.Nullable; @@ -48,6 +49,7 @@ import android.window.WindowOrganizer; import com.android.internal.os.SomeArgs; import com.android.systemui.R; import com.android.systemui.pip.phone.PipUpdateThread; +import com.android.systemui.stackdivider.Divider; import java.util.ArrayList; import java.util.HashMap; @@ -85,6 +87,7 @@ public class PipTaskOrganizer extends TaskOrganizer { private final int mEnterExitAnimationDuration; private final PipSurfaceTransactionHelper mSurfaceTransactionHelper; private final Map<IBinder, Rect> mBoundsToRestore = new HashMap<>(); + private final Divider mSplitDivider; // These callbacks are called on the update thread private final PipAnimationController.PipAnimationCallback mPipAnimationCallback = @@ -189,7 +192,8 @@ public class PipTaskOrganizer extends TaskOrganizer { mSurfaceControlTransactionFactory; public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler, - @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper) { + @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper, + @Nullable Divider divider) { mMainHandler = new Handler(Looper.getMainLooper()); mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks); mPipBoundsHandler = boundsHandler; @@ -198,6 +202,7 @@ public class PipTaskOrganizer extends TaskOrganizer { mSurfaceTransactionHelper = surfaceTransactionHelper; mPipAnimationController = new PipAnimationController(context, surfaceTransactionHelper); mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new; + mSplitDivider = divider; } public Handler getUpdateHandler() { @@ -226,20 +231,21 @@ public class PipTaskOrganizer extends TaskOrganizer { /** * Dismiss PiP, this is done in two phases using {@link WindowContainerTransaction} - * - setActivityWindowingMode to fullscreen at beginning of the transaction. without changing - * the windowing mode of the Task itself. This makes sure the activity render it's fullscreen + * - setActivityWindowingMode to undefined at beginning of the transaction. without changing + * the windowing mode of the Task itself. This makes sure the activity render it's final * configuration while the Task is still in PiP. - * - setWindowingMode to fullscreen at the end of transition + * - setWindowingMode to undefined at the end of transition * @param animationDurationMs duration in millisecond for the exiting PiP transition */ public void dismissPip(int animationDurationMs) { final WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN); + wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); WindowOrganizer.applyTransaction(wct); final Rect destinationBounds = mBoundsToRestore.remove(mToken.asBinder()); + final int direction = syncWithSplitScreenBounds(destinationBounds) + ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN : TRANSITION_DIRECTION_TO_FULLSCREEN; scheduleAnimateResizePip(mLastReportedBounds, destinationBounds, - TRANSITION_DIRECTION_TO_FULLSCREEN, animationDurationMs, - null /* updateBoundsCallback */); + direction, animationDurationMs, null /* updateBoundsCallback */); mInPip = false; } @@ -282,6 +288,9 @@ public class PipTaskOrganizer extends TaskOrganizer { */ @Override public void onTaskVanished(ActivityManager.RunningTaskInfo info) { + if (!mInPip) { + return; + } final WindowContainerToken token = info.token; Objects.requireNonNull(token, "Requires valid WindowContainerToken"); if (token.asBinder() != mToken.asBinder()) { @@ -519,14 +528,13 @@ public class PipTaskOrganizer extends TaskOrganizer { mLastReportedBounds.set(destinationBounds); final WindowContainerTransaction wct = new WindowContainerTransaction(); final Rect taskBounds; - if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) { + if (isOutPipDirection(direction)) { // If we are animating to fullscreen, then we need to reset the override bounds - // on the task to ensure that the task "matches" the parent's bounds, this applies - // also to the final windowing mode, which should be reset to undefined rather than - // fullscreen. - taskBounds = null; - wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED) - .setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); + // on the task to ensure that the task "matches" the parent's bounds. + taskBounds = (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) + ? null : destinationBounds; + // As for the final windowing mode, simply reset it to undefined. + wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); } else { taskBounds = destinationBounds; } @@ -578,6 +586,24 @@ public class PipTaskOrganizer extends TaskOrganizer { } /** + * Sync with {@link #mSplitDivider} on destination bounds if PiP is going to split screen. + * + * @param destinationBoundsOut contain the updated destination bounds if applicable + * @return {@code true} if destinationBounds is altered for split screen + */ + private boolean syncWithSplitScreenBounds(Rect destinationBoundsOut) { + if (mSplitDivider == null || !mSplitDivider.inSplitMode()) { + // bail early if system is not in split screen mode + return false; + } + // PiP window will go to split-secondary mode instead of fullscreen, populates the + // split screen bounds here. + destinationBoundsOut.set( + mSplitDivider.getView().getNonMinimizedSplitScreenSecondaryBounds()); + return true; + } + + /** * Callback interface for PiP transitions (both from and to PiP mode) */ public interface PipTransitionCallback { diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java index ba9a30fb554f..78975735ef0f 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -19,7 +19,7 @@ package com.android.systemui.pip.phone; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; -import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN; +import static com.android.systemui.pip.PipAnimationController.isOutPipDirection; import android.annotation.Nullable; import android.app.ActivityManager; @@ -53,6 +53,7 @@ import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.WindowManagerWrapper; +import com.android.systemui.stackdivider.Divider; import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.FloatingContentCoordinator; import com.android.systemui.wm.DisplayChangeController; @@ -199,7 +200,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio DeviceConfigProxy deviceConfig, PipBoundsHandler pipBoundsHandler, PipSnapAlgorithm pipSnapAlgorithm, - PipSurfaceTransactionHelper surfaceTransactionHelper) { + PipSurfaceTransactionHelper surfaceTransactionHelper, + Divider divider) { mContext = context; mActivityManager = ActivityManager.getService(); @@ -214,7 +216,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio final IActivityTaskManager activityTaskManager = ActivityTaskManager.getService(); mPipBoundsHandler = pipBoundsHandler; mPipTaskOrganizer = new PipTaskOrganizer(context, pipBoundsHandler, - surfaceTransactionHelper); + surfaceTransactionHelper, divider); mPipTaskOrganizer.registerPipTransitionCallback(this); mInputConsumerController = InputConsumerController.getPipInputConsumer(); mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher); @@ -312,7 +314,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Override public void onPipTransitionStarted(ComponentName activity, int direction) { - if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) { + if (isOutPipDirection(direction)) { // On phones, the expansion animation that happens on pip tap before restoring // to fullscreen makes it so that the bounds received here are the expanded // bounds. We want to restore to the unexpanded bounds when re-entering pip, diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java index 3a2d786cebe4..6c5312d57b2a 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java @@ -57,6 +57,7 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.WindowManagerWrapper; +import com.android.systemui.stackdivider.Divider; import java.util.ArrayList; import java.util.List; @@ -232,7 +233,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Inject public PipManager(Context context, BroadcastDispatcher broadcastDispatcher, PipBoundsHandler pipBoundsHandler, - PipSurfaceTransactionHelper surfaceTransactionHelper) { + PipSurfaceTransactionHelper surfaceTransactionHelper, + Divider divider) { if (mInitialized) { return; } @@ -249,7 +251,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio mResizeAnimationDuration = context.getResources() .getInteger(R.integer.config_pipResizeAnimationDuration); mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler, - surfaceTransactionHelper); + surfaceTransactionHelper, divider); mPipTaskOrganizer.registerPipTransitionCallback(this); mActivityTaskManager = ActivityTaskManager.getService(); ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java index 9e574a1fa621..e76cd5116818 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java @@ -41,6 +41,7 @@ import com.android.systemui.R; import com.android.systemui.media.MediaControlPanel; import com.android.systemui.media.SeekBarObserver; import com.android.systemui.media.SeekBarViewModel; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.util.concurrency.DelayableExecutor; import java.util.concurrent.Executor; @@ -75,11 +76,13 @@ public class QSMediaPlayer extends MediaControlPanel { * @param routeManager Provides information about device * @param foregroundExecutor * @param backgroundExecutor + * @param activityStarter */ public QSMediaPlayer(Context context, ViewGroup parent, LocalMediaManager routeManager, - Executor foregroundExecutor, DelayableExecutor backgroundExecutor) { + Executor foregroundExecutor, DelayableExecutor backgroundExecutor, + ActivityStarter activityStarter) { super(context, parent, routeManager, R.layout.qs_media_panel, QS_ACTION_IDS, - foregroundExecutor, backgroundExecutor); + foregroundExecutor, backgroundExecutor, activityStarter); mParent = (QSPanel) parent; mForegroundExecutor = foregroundExecutor; mBackgroundExecutor = backgroundExecutor; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 1252008755a7..c7ce1af0c1fb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -65,6 +65,7 @@ import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.media.MediaControlPanel; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTileView; @@ -114,6 +115,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne private final Executor mForegroundExecutor; private final DelayableExecutor mBackgroundExecutor; private boolean mUpdateCarousel = false; + private ActivityStarter mActivityStarter; protected boolean mExpanded; protected boolean mListening; @@ -158,7 +160,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne QSLogger qsLogger, @Main Executor foregroundExecutor, @Background DelayableExecutor backgroundExecutor, - @Nullable LocalBluetoothManager localBluetoothManager + @Nullable LocalBluetoothManager localBluetoothManager, + ActivityStarter activityStarter ) { super(context, attrs); mContext = context; @@ -168,6 +171,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne mBackgroundExecutor = backgroundExecutor; mLocalBluetoothManager = localBluetoothManager; mBroadcastDispatcher = broadcastDispatcher; + mActivityStarter = activityStarter; setOrientation(VERTICAL); @@ -284,7 +288,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne imm, notif.getPackageName()); player = new QSMediaPlayer(mContext, this, routeManager, mForegroundExecutor, - mBackgroundExecutor); + mBackgroundExecutor, mActivityStarter); player.setListening(mListening); if (player.isPlaying()) { mMediaCarousel.addView(player.getView(), 0, lp); // add in front @@ -341,7 +345,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne Log.d(TAG, "adding track from browser: " + desc + ", " + component); QSMediaPlayer player = new QSMediaPlayer(mContext, QSPanel.this, - null, mForegroundExecutor, mBackgroundExecutor); + null, mForegroundExecutor, mBackgroundExecutor, mActivityStarter); String pkgName = component.getPackageName(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java index 89b36da0c834..f77ff8cd7949 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java @@ -29,6 +29,7 @@ import android.widget.LinearLayout; import com.android.systemui.R; import com.android.systemui.media.MediaControlPanel; +import com.android.systemui.plugins.ActivityStarter; import java.util.concurrent.Executor; @@ -48,11 +49,12 @@ public class QuickQSMediaPlayer extends MediaControlPanel { * @param parent * @param foregroundExecutor * @param backgroundExecutor + * @param activityStarter */ public QuickQSMediaPlayer(Context context, ViewGroup parent, Executor foregroundExecutor, - Executor backgroundExecutor) { + Executor backgroundExecutor, ActivityStarter activityStarter) { super(context, parent, null, R.layout.qqs_media_panel, QQS_ACTION_IDS, - foregroundExecutor, backgroundExecutor); + foregroundExecutor, backgroundExecutor, activityStarter); } /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java index 2169677b83fb..becf9da800b3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java @@ -34,6 +34,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.SignalState; import com.android.systemui.plugins.qs.QSTile.State; @@ -84,10 +85,11 @@ public class QuickQSPanel extends QSPanel { QSLogger qsLogger, @Main Executor foregroundExecutor, @Background DelayableExecutor backgroundExecutor, - @Nullable LocalBluetoothManager localBluetoothManager + @Nullable LocalBluetoothManager localBluetoothManager, + ActivityStarter activityStarter ) { super(context, attrs, dumpManager, broadcastDispatcher, qsLogger, - foregroundExecutor, backgroundExecutor, localBluetoothManager); + foregroundExecutor, backgroundExecutor, localBluetoothManager, activityStarter); if (mFooter != null) { removeView(mFooter.getView()); } @@ -107,7 +109,7 @@ public class QuickQSPanel extends QSPanel { int marginSize = (int) mContext.getResources().getDimension(R.dimen.qqs_media_spacing); mMediaPlayer = new QuickQSMediaPlayer(mContext, mHorizontalLinearLayout, - foregroundExecutor, backgroundExecutor); + foregroundExecutor, backgroundExecutor, activityStarter); LayoutParams lp2 = new LayoutParams(0, LayoutParams.MATCH_PARENT, 1); lp2.setMarginEnd(marginSize); lp2.setMarginStart(0); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java index 1a6a104387ac..da7890324950 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java @@ -23,6 +23,7 @@ import android.util.Log; import android.widget.Switch; import com.android.systemui.R; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; @@ -37,14 +38,17 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> implements RecordingController.RecordingStateChangeCallback { private static final String TAG = "ScreenRecordTile"; private RecordingController mController; + private ActivityStarter mActivityStarter; private long mMillisUntilFinished = 0; private Callback mCallback = new Callback(); @Inject - public ScreenRecordTile(QSHost host, RecordingController controller) { + public ScreenRecordTile(QSHost host, RecordingController controller, + ActivityStarter activityStarter) { super(host); mController = controller; mController.observe(this, mCallback); + mActivityStarter = activityStarter; } @Override @@ -115,7 +119,8 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> Log.d(TAG, "Starting countdown"); // Close QS, otherwise the permission dialog appears beneath it getHost().collapsePanels(); - mController.launchRecordPrompt(); + Intent intent = mController.getPromptIntent(); + mActivityStarter.postStartActivityDismissingKeyguard(intent, 0); } private void cancelCountdown() { diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java index 8dad08e49d80..ae0a1c4d9822 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java @@ -59,15 +59,15 @@ public class RecordingController } /** - * Show dialog of screen recording options to user. + * Get an intent to show screen recording options to the user. */ - public void launchRecordPrompt() { + public Intent getPromptIntent() { final ComponentName launcherComponent = new ComponentName(SYSUI_PACKAGE, SYSUI_SCREENRECORD_LAUNCHER); final Intent intent = new Intent(); intent.setComponent(launcherComponent); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(intent); + return intent; } /** diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 1efe663ca6ce..70454d4d63df 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -36,6 +36,7 @@ import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Insets; @@ -184,9 +185,11 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset private final LinearLayout mActionsView; private final ImageView mBackgroundProtection; private final FrameLayout mDismissButton; + private final ImageView mDismissImage; private Bitmap mScreenBitmap; private Animator mScreenshotAnimation; + private boolean mInDarkMode = false; private float mScreenshotOffsetXPx; private float mScreenshotOffsetYPx; @@ -250,6 +253,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EXPLICIT_DISMISSAL); clearScreenshot("dismiss_button"); }); + mDismissImage = mDismissButton.findViewById(R.id.global_screenshot_dismiss_image); mScreenshotFlash = mScreenshotLayout.findViewById(R.id.global_screenshot_flash); mScreenshotSelectorView = mScreenshotLayout.findViewById(R.id.global_screenshot_selector); @@ -356,6 +360,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset mScreenBitmap.setHasAlpha(false); mScreenBitmap.prepareToDraw(); + updateDarkTheme(); + mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams); mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this); @@ -434,7 +440,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset * Clears current screenshot */ private void clearScreenshot(String reason) { - Log.e(TAG, "clearing screenshot: " + reason); + Log.v(TAG, "clearing screenshot: " + reason); if (mScreenshotLayout.isAttachedToWindow()) { mWindowManager.removeView(mScreenshotLayout); } @@ -454,6 +460,41 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset } /** + * Update assets (called when the dark theme status changes). We only need to update the dismiss + * button and the actions container background, since the buttons are re-inflated on demand. + */ + private void reloadAssets() { + mDismissImage.setImageDrawable(mContext.getDrawable(R.drawable.screenshot_cancel)); + mActionsContainer.setBackground( + mContext.getDrawable(R.drawable.action_chip_container_background)); + + } + + /** + * Checks the current dark theme status and updates if it has changed. + */ + private void updateDarkTheme() { + int currentNightMode = mContext.getResources().getConfiguration().uiMode + & Configuration.UI_MODE_NIGHT_MASK; + switch (currentNightMode) { + case Configuration.UI_MODE_NIGHT_NO: + // Night mode is not active, we're using the light theme + if (mInDarkMode) { + mInDarkMode = false; + reloadAssets(); + } + break; + case Configuration.UI_MODE_NIGHT_YES: + // Night mode is active, we're using dark theme + if (!mInDarkMode) { + mInDarkMode = true; + reloadAssets(); + } + break; + } + } + + /** * Starts the animation after taking the screenshot */ private void startAnimation(final Consumer<Uri> finisher, int w, int h, @@ -660,7 +701,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset R.layout.global_screenshot_action_chip, mActionsView, false); Toast scrollNotImplemented = Toast.makeText( mContext, "Not implemented", Toast.LENGTH_SHORT); - scrollChip.setText("Extend"); // TODO : add resource and translate + scrollChip.setText("Extend"); // TODO: add resource and translate scrollChip.setIcon( Icon.createWithResource(mContext, R.drawable.ic_arrow_downward), true); scrollChip.setOnClickListener(v -> { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java index a6e083b04ea3..f68cb745e4c8 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java @@ -132,7 +132,7 @@ public class TakeScreenshotService extends Service { @Override public boolean onUnbind(Intent intent) { if (mScreenshot != null) mScreenshot.stopScreenshot(); - // TODO (mkephart) remove once notifications flow is fully deprecated + // TODO remove once notifications flow is fully deprecated if (mScreenshotLegacy != null) mScreenshotLegacy.stopScreenshot(); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt index 4de978c77128..825a7f3dbadb 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt +++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt @@ -22,14 +22,13 @@ import androidx.annotation.VisibleForTesting import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.util.Assert import java.lang.IllegalStateException -import javax.inject.Inject -import javax.inject.Singleton /** * Tracks a reference to the context for the current user + * + * Constructor is injected at SettingsModule */ -@Singleton -class CurrentUserContextTracker @Inject constructor( +class CurrentUserContextTracker internal constructor( private val sysuiContext: Context, broadcastDispatcher: BroadcastDispatcher ) { diff --git a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java b/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java new file mode 100644 index 000000000000..2c5c3ceb6e66 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.settings.dagger; + +import android.content.Context; + +import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.settings.CurrentUserContextTracker; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +/** + * Dagger Module for classes found within the com.android.systemui.settings package. + */ +@Module +public interface SettingsModule { + + /** + * Provides and initializes a CurrentUserContextTracker + */ + @Singleton + @Provides + static CurrentUserContextTracker provideCurrentUserContextTracker( + Context context, + BroadcastDispatcher broadcastDispatcher) { + CurrentUserContextTracker tracker = + new CurrentUserContextTracker(context, broadcastDispatcher); + tracker.initialize(); + return tracker; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java index a4b1310687aa..f5d6cb6fd4b0 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java @@ -33,10 +33,8 @@ import android.view.SurfaceControl; import android.view.SurfaceSession; import android.window.TaskOrganizer; -import java.util.ArrayList; - class SplitScreenTaskOrganizer extends TaskOrganizer { - private static final String TAG = "SplitScreenTaskOrganizer"; + private static final String TAG = "SplitScreenTaskOrg"; private static final boolean DEBUG = Divider.DEBUG; RunningTaskInfo mPrimary; @@ -45,7 +43,6 @@ class SplitScreenTaskOrganizer extends TaskOrganizer { SurfaceControl mSecondarySurface; SurfaceControl mPrimaryDim; SurfaceControl mSecondaryDim; - ArrayList<SurfaceControl> mHomeAndRecentsSurfaces = new ArrayList<>(); Rect mHomeBounds = new Rect(); final Divider mDivider; private boolean mSplitScreenSupported = false; @@ -110,6 +107,15 @@ class SplitScreenTaskOrganizer extends TaskOrganizer { * presentations based on the contents of the split regions. */ private void handleTaskInfoChanged(RunningTaskInfo info) { + if (!mSplitScreenSupported) { + // This shouldn't happen; but apparently there is a chance that SysUI crashes without + // system server receiving binder-death (or maybe it receives binder-death too late?). + // In this situation, when sys-ui restarts, the split root-tasks will still exist so + // there is a small window of time during init() where WM might send messages here + // before init() fails. So, avoid a cycle of crashes by returning early. + Log.e(TAG, "Got handleTaskInfoChanged when not initialized: " + info); + return; + } final boolean secondaryWasHomeOrRecents = mSecondary.topActivityType == ACTIVITY_TYPE_HOME || mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS; final boolean primaryWasEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED; diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java index 5aa7946bcb7f..3027bd225216 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java @@ -174,12 +174,8 @@ public class WindowManagerProxy { if (rootTasks.isEmpty()) { return false; } - tiles.mHomeAndRecentsSurfaces.clear(); for (int i = rootTasks.size() - 1; i >= 0; --i) { final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i); - if (isHomeOrRecentTask(rootTask)) { - tiles.mHomeAndRecentsSurfaces.add(rootTask.token.getLeash()); - } // Only move resizeable task to split secondary. WM will just ignore this anyways... if (!rootTask.isResizable()) continue; // Only move fullscreen tasks to split secondary. @@ -211,7 +207,6 @@ public class WindowManagerProxy { // Set launch root first so that any task created after getChildContainers and // before reparent (pretty unlikely) are put into fullscreen. TaskOrganizer.setLaunchRoot(Display.DEFAULT_DISPLAY, null); - tiles.mHomeAndRecentsSurfaces.clear(); // TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished // plus specific APIs to clean this up. List<ActivityManager.RunningTaskInfo> primaryChildren = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 11b54ad19636..43b47232d27d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -311,7 +311,7 @@ public class KeyguardIndicationController implements StateListener, mTextView.switchIndication(mTransientIndication); } else if (!TextUtils.isEmpty(mAlignmentIndication)) { mTextView.switchIndication(mAlignmentIndication); - mTextView.setTextColor(Utils.getColorError(mContext)); + mTextView.setTextColor(mContext.getColor(R.color.misalignment_text_color)); } else if (mPowerPluggedIn) { String indication = computePowerIndication(); if (animate) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java index afb50027f03d..02c41e5aaefe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java @@ -35,6 +35,7 @@ import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.inflation.LowPriorityInflationHelper; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; @@ -71,6 +72,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle protected final VisualStabilityManager mVisualStabilityManager; private final SysuiStatusBarStateController mStatusBarStateController; private final NotificationEntryManager mEntryManager; + private final LowPriorityInflationHelper mLowPriorityInflationHelper; /** * {@code true} if notifications not part of a group should by default be rendered in their @@ -108,7 +110,8 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle BubbleController bubbleController, DynamicPrivacyController privacyController, ForegroundServiceSectionController fgsSectionController, - DynamicChildBindController dynamicChildBindController) { + DynamicChildBindController dynamicChildBindController, + LowPriorityInflationHelper lowPriorityInflationHelper) { mContext = context; mHandler = mainHandler; mLockscreenUserManager = notificationLockscreenUserManager; @@ -124,6 +127,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle mBubbleController = bubbleController; mDynamicPrivacyController = privacyController; mDynamicChildBindController = dynamicChildBindController; + mLowPriorityInflationHelper = lowPriorityInflationHelper; } public void setUpWithPresenter(NotificationPresenter presenter, @@ -177,6 +181,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle currentUserId); ent.setSensitive(sensitive, deviceSensitive); ent.getRow().setNeedsRedaction(needsRedaction); + mLowPriorityInflationHelper.recheckLowPriorityViewAndInflate(ent, ent.getRow()); boolean isChildInGroup = mGroupManager.isChildInGroupWithSummary(ent.getSbn()); boolean groupChangesAllowed = mVisualStabilityManager.areGroupChangesAllowed() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java index e64b423aab60..de7e36d97b22 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java @@ -37,6 +37,7 @@ import com.android.systemui.statusbar.notification.DynamicChildBindController; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.VisualStabilityManager; +import com.android.systemui.statusbar.notification.collection.inflation.LowPriorityInflationHelper; import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationGroupManager; @@ -143,7 +144,8 @@ public interface StatusBarDependenciesModule { BubbleController bubbleController, DynamicPrivacyController privacyController, ForegroundServiceSectionController fgsSectionController, - DynamicChildBindController dynamicChildBindController) { + DynamicChildBindController dynamicChildBindController, + LowPriorityInflationHelper lowPriorityInflationHelper) { return new NotificationViewHierarchyManager( context, mainHandler, @@ -156,7 +158,8 @@ public interface StatusBarDependenciesModule { bubbleController, privacyController, fgsSectionController, - dynamicChildBindController); + dynamicChildBindController, + lowPriorityInflationHelper); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java index 4e6df0ad1ba4..d364689a65d4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java @@ -23,11 +23,14 @@ import android.view.View; import com.android.systemui.DejankUtils; import com.android.systemui.bubbles.BubbleController; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.phone.StatusBar; import java.util.Optional; +import javax.inject.Inject; + /** * Click handler for generic clicks on notifications. Clicks on specific areas (expansion caret, * app ops icon, etc) are handled elsewhere. @@ -35,15 +38,19 @@ import java.util.Optional; public final class NotificationClicker implements View.OnClickListener { private static final String TAG = "NotificationClicker"; - private final Optional<StatusBar> mStatusBar; private final BubbleController mBubbleController; + private final NotificationClickerLogger mLogger; + private final Optional<StatusBar> mStatusBar; private final NotificationActivityStarter mNotificationActivityStarter; - public NotificationClicker(Optional<StatusBar> statusBar, + private NotificationClicker( BubbleController bubbleController, + NotificationClickerLogger logger, + Optional<StatusBar> statusBar, NotificationActivityStarter notificationActivityStarter) { - mStatusBar = statusBar; mBubbleController = bubbleController; + mLogger = logger; + mStatusBar = statusBar; mNotificationActivityStarter = notificationActivityStarter; } @@ -58,25 +65,26 @@ public final class NotificationClicker implements View.OnClickListener { SystemClock.uptimeMillis(), v, "NOTIFICATION_CLICK")); final ExpandableNotificationRow row = (ExpandableNotificationRow) v; - final StatusBarNotification sbn = row.getEntry().getSbn(); - if (sbn == null) { - Log.e(TAG, "NotificationClicker called on an unclickable notification,"); - return; - } + final NotificationEntry entry = row.getEntry(); + mLogger.logOnClick(entry); // Check if the notification is displaying the menu, if so slide notification back if (isMenuVisible(row)) { + mLogger.logMenuVisible(entry); row.animateTranslateNotification(0); return; } else if (row.isChildInGroup() && isMenuVisible(row.getNotificationParent())) { + mLogger.logParentMenuVisible(entry); row.getNotificationParent().animateTranslateNotification(0); return; } else if (row.isSummaryWithChildren() && row.areChildrenExpanded()) { // We never want to open the app directly if the user clicks in between // the notifications. + mLogger.logChildrenExpanded(entry); return; } else if (row.areGutsExposed()) { // ignore click if guts are exposed + mLogger.logGutsExposed(entry); return; } @@ -88,7 +96,7 @@ public final class NotificationClicker implements View.OnClickListener { mBubbleController.collapseStack(); } - mNotificationActivityStarter.onNotificationClicked(sbn, row); + mNotificationActivityStarter.onNotificationClicked(entry.getSbn(), row); } private boolean isMenuVisible(ExpandableNotificationRow row) { @@ -107,4 +115,30 @@ public final class NotificationClicker implements View.OnClickListener { row.setOnClickListener(null); } } + + /** Daggerized builder for NotificationClicker. */ + public static class Builder { + private final BubbleController mBubbleController; + private final NotificationClickerLogger mLogger; + + @Inject + public Builder( + BubbleController bubbleController, + NotificationClickerLogger logger) { + mBubbleController = bubbleController; + mLogger = logger; + } + + /** Builds an instance. */ + public NotificationClicker build( + Optional<StatusBar> statusBar, + NotificationActivityStarter notificationActivityStarter + ) { + return new NotificationClicker( + mBubbleController, + mLogger, + statusBar, + notificationActivityStarter); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClickerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClickerLogger.kt new file mode 100644 index 000000000000..fbf033bd2291 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClickerLogger.kt @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification + +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.LogLevel +import com.android.systemui.log.dagger.NotifInteractionLog +import com.android.systemui.statusbar.notification.collection.NotificationEntry +import javax.inject.Inject + +class NotificationClickerLogger @Inject constructor( + @NotifInteractionLog private val buffer: LogBuffer +) { + fun logOnClick(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { + str1 = entry.key + str2 = entry.ranking.channel.id + }, { + "CLICK $str1 (channel=$str2)" + }) + } + + fun logMenuVisible(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { + str1 = entry.key + }, { + "Ignoring click on $str1; menu is visible" + }) + } + + fun logParentMenuVisible(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { + str1 = entry.key + }, { + "Ignoring click on $str1; parent menu is visible" + }) + } + + fun logChildrenExpanded(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { + str1 = entry.key + }, { + "Ignoring click on $str1; children are expanded" + }) + } + + fun logGutsExposed(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { + str1 = entry.key + }, { + "Ignoring click on $str1; guts are exposed" + }) + } +} + +private const val TAG = "NotificationClicker" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java index 12d190b26eba..f1cb783742bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java @@ -619,7 +619,8 @@ public class NotificationEntryManager implements entry.setSbn(notification); for (NotifCollectionListener listener : mNotifCollectionListeners) { listener.onEntryBind(entry, notification); - } mGroupManager.onEntryUpdated(entry, oldSbn); + } + mGroupManager.onEntryUpdated(entry, oldSbn); mLogger.logNotifUpdated(entry.getKey()); for (NotificationEntryListener listener : mNotificationEntryListeners) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/LowPriorityInflationHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/LowPriorityInflationHelper.java new file mode 100644 index 000000000000..73c0fdc56b8d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/LowPriorityInflationHelper.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.collection.inflation; + +import com.android.systemui.statusbar.FeatureFlags; +import com.android.systemui.statusbar.notification.collection.GroupEntry; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; +import com.android.systemui.statusbar.notification.row.RowContentBindParams; +import com.android.systemui.statusbar.notification.row.RowContentBindStage; +import com.android.systemui.statusbar.phone.NotificationGroupManager; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Helper class that provide methods to help check when we need to inflate a low priority version + * ot notification content. + */ +@Singleton +public class LowPriorityInflationHelper { + private final FeatureFlags mFeatureFlags; + private final NotificationGroupManager mGroupManager; + private final RowContentBindStage mRowContentBindStage; + + @Inject + LowPriorityInflationHelper( + FeatureFlags featureFlags, + NotificationGroupManager groupManager, + RowContentBindStage rowContentBindStage) { + mFeatureFlags = featureFlags; + mGroupManager = groupManager; + mRowContentBindStage = rowContentBindStage; + } + + /** + * Check if we inflated the wrong version of the view and if we need to reinflate the + * content views to be their low priority version or not. + * + * Whether we inflate the low priority view or not depends on the notification being visually + * part of a group. Since group membership is determined AFTER inflation, we're forced to check + * again at a later point in the pipeline to see if we inflated the wrong view and reinflate + * the correct one here. + * + * TODO: The group manager should run before inflation so that we don't deal with this + */ + public void recheckLowPriorityViewAndInflate( + NotificationEntry entry, + ExpandableNotificationRow row) { + RowContentBindParams params = mRowContentBindStage.getStageParams(entry); + final boolean shouldBeLowPriority = shouldUseLowPriorityView(entry); + if (!row.isRemoved() && row.isLowPriority() != shouldBeLowPriority) { + params.setUseLowPriority(shouldBeLowPriority); + mRowContentBindStage.requestRebind(entry, + en -> row.setIsLowPriority(shouldBeLowPriority)); + } + } + + /** + * Whether the notification should inflate a low priority version of its content views. + */ + public boolean shouldUseLowPriorityView(NotificationEntry entry) { + boolean isGroupChild; + if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) { + isGroupChild = (entry.getParent() != GroupEntry.ROOT_ENTRY); + } else { + isGroupChild = mGroupManager.isChildInGroupWithSummary(entry.getSbn()); + } + return entry.isAmbient() && !isGroupChild; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java index e6a4cff0d893..673aa3903156 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java @@ -64,6 +64,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { private final ExpandableNotificationRowComponent.Builder mExpandableNotificationRowComponentBuilder; private final IconManager mIconManager; + private final LowPriorityInflationHelper mLowPriorityInflationHelper; private NotificationPresenter mPresenter; private NotificationListContainer mListContainer; @@ -81,7 +82,8 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { NotificationInterruptStateProvider notificationInterruptionStateProvider, Provider<RowInflaterTask> rowInflaterTaskProvider, ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder, - IconManager iconManager) { + IconManager iconManager, + LowPriorityInflationHelper lowPriorityInflationHelper) { mContext = context; mNotifBindPipeline = notifBindPipeline; mRowContentBindStage = rowContentBindStage; @@ -92,6 +94,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { mRowInflaterTaskProvider = rowInflaterTaskProvider; mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder; mIconManager = iconManager; + mLowPriorityInflationHelper = lowPriorityInflationHelper; } /** @@ -225,11 +228,15 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { @Nullable NotificationRowContentBinder.InflationCallback inflationCallback) { final boolean useIncreasedCollapsedHeight = mMessagingUtil.isImportantMessaging(entry.getSbn(), entry.getImportance()); - final boolean isLowPriority = entry.isAmbient(); + // If this is our first time inflating, we don't actually know the groupings for real + // yet, so we might actually inflate a low priority content view incorrectly here and have + // to correct it later in the pipeline. On subsequent inflations (i.e. updates), this + // should inflate the correct view. + final boolean isLowPriority = mLowPriorityInflationHelper.shouldUseLowPriorityView(entry); RowContentBindParams params = mRowContentBindStage.getStageParams(entry); params.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight); - params.setUseLowPriority(entry.isAmbient()); + params.setUseLowPriority(isLowPriority); // TODO: Replace this API with RowContentBindParams directly. Also move to a separate // redaction controller. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt index 7f2f898565d8..c9754048e1d1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.notification.init import android.service.notification.StatusBarNotification -import com.android.systemui.bubbles.BubbleController import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption import com.android.systemui.statusbar.FeatureFlags import com.android.systemui.statusbar.NotificationListener @@ -62,12 +61,12 @@ class NotificationsControllerImpl @Inject constructor( private val deviceProvisionedController: DeviceProvisionedController, private val notificationRowBinder: NotificationRowBinderImpl, private val remoteInputUriController: RemoteInputUriController, - private val bubbleController: BubbleController, private val groupManager: NotificationGroupManager, private val groupAlertTransferHelper: NotificationGroupAlertTransferHelper, private val headsUpManager: HeadsUpManager, private val headsUpController: HeadsUpController, - private val headsUpViewBinder: HeadsUpViewBinder + private val headsUpViewBinder: HeadsUpViewBinder, + private val clickerBuilder: NotificationClicker.Builder ) : NotificationsController { override fun initialize( @@ -87,10 +86,7 @@ class NotificationsControllerImpl @Inject constructor( listController.bind() notificationRowBinder.setNotificationClicker( - NotificationClicker( - Optional.of(statusBar), - bubbleController, - notificationActivityStarter)) + clickerBuilder.build(Optional.of(statusBar), notificationActivityStarter)) notificationRowBinder.setUpWithPresenter( presenter, listContainer, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java index b9dd97482d88..92b597b01559 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java @@ -331,19 +331,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView .setDuration(ACTIVATE_ANIMATION_LENGTH); } - @Override - public boolean performClick() { - if (!mNeedsDimming || (mAccessibilityManager != null - && mAccessibilityManager.isTouchExplorationEnabled())) { - return super.performClick(); - } - return false; - } - - boolean superPerformClick() { - return super.performClick(); - } - /** * Cancels the hotspot and makes the notification inactive. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java index 2f0e433b3927..dd30c890e75b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java @@ -72,7 +72,7 @@ public class ActivatableNotificationViewController { } else { mView.makeInactive(true /* animate */); } - }, mView::superPerformClick, mView::handleSlideBack, + }, mView::performClick, mView::handleSlideBack, mFalsingManager::onNotificationDoubleTap); mView.setOnTouchListener(mTouchHandler); mView.setTouchHandler(mTouchHandler); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index c613e6443882..ba72e2879f14 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -240,7 +240,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private ExpandableNotificationRow mNotificationParent; private OnExpandClickListener mOnExpandClickListener; private View.OnClickListener mOnAppOpsClickListener; - private boolean mIsChildInGroup; // Listener will be called when receiving a long click event. // Use #setLongPressPosition to optionally assign positional data with the long press. @@ -848,15 +847,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } mNotificationParent = isChildInGroup ? parent : null; mPrivateLayout.setIsChildInGroup(isChildInGroup); - // TODO: Move inflation logic out of this call - if (mIsChildInGroup != isChildInGroup) { - mIsChildInGroup = isChildInGroup; - if (!isRemoved() && mIsLowPriority) { - RowContentBindParams params = mRowContentBindStage.getStageParams(mEntry); - params.setUseLowPriority(mIsLowPriority); - mRowContentBindStage.requestRebind(mEntry, null /* callback */); - } - } + resetBackgroundAlpha(); updateBackgroundForGroupState(); updateClickAndFocus(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java index 9d5443729d45..582e3e5b6c34 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java @@ -132,7 +132,6 @@ public class NotificationContentInflater implements NotificationRowContentBinder mConversationProcessor, row, bindParams.isLowPriority, - bindParams.isChildInGroup, bindParams.usesIncreasedHeight, bindParams.usesIncreasedHeadsUpHeight, callback, @@ -156,7 +155,6 @@ public class NotificationContentInflater implements NotificationRowContentBinder InflationProgress result = createRemoteViews(reInflateFlags, builder, bindParams.isLowPriority, - bindParams.isChildInGroup, bindParams.usesIncreasedHeight, bindParams.usesIncreasedHeadsUpHeight, packageContext); @@ -285,11 +283,9 @@ public class NotificationContentInflater implements NotificationRowContentBinder } private static InflationProgress createRemoteViews(@InflationFlag int reInflateFlags, - Notification.Builder builder, boolean isLowPriority, boolean isChildInGroup, - boolean usesIncreasedHeight, boolean usesIncreasedHeadsUpHeight, - Context packageContext) { + Notification.Builder builder, boolean isLowPriority, boolean usesIncreasedHeight, + boolean usesIncreasedHeadsUpHeight, Context packageContext) { InflationProgress result = new InflationProgress(); - isLowPriority = isLowPriority && !isChildInGroup; if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) { result.newContentView = createContentView(builder, isLowPriority, usesIncreasedHeight); @@ -702,7 +698,6 @@ public class NotificationContentInflater implements NotificationRowContentBinder private final Context mContext; private final boolean mInflateSynchronously; private final boolean mIsLowPriority; - private final boolean mIsChildInGroup; private final boolean mUsesIncreasedHeight; private final InflationCallback mCallback; private final boolean mUsesIncreasedHeadsUpHeight; @@ -728,7 +723,6 @@ public class NotificationContentInflater implements NotificationRowContentBinder ConversationNotificationProcessor conversationProcessor, ExpandableNotificationRow row, boolean isLowPriority, - boolean isChildInGroup, boolean usesIncreasedHeight, boolean usesIncreasedHeadsUpHeight, InflationCallback callback, @@ -743,7 +737,6 @@ public class NotificationContentInflater implements NotificationRowContentBinder mRemoteViewCache = cache; mContext = mRow.getContext(); mIsLowPriority = isLowPriority; - mIsChildInGroup = isChildInGroup; mUsesIncreasedHeight = usesIncreasedHeight; mUsesIncreasedHeadsUpHeight = usesIncreasedHeadsUpHeight; mRemoteViewClickHandler = remoteViewClickHandler; @@ -781,7 +774,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder mConversationProcessor.processNotification(mEntry, recoveredBuilder); } InflationProgress inflationProgress = createRemoteViews(mReInflateFlags, - recoveredBuilder, mIsLowPriority, mIsChildInGroup, mUsesIncreasedHeight, + recoveredBuilder, mIsLowPriority, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, packageContext); return inflateSmartReplyViews(inflationProgress, mReInflateFlags, mEntry, mRow.getContext(), packageContext, mRow.getHeadsUpManager(), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java index 9bd8d4782672..a9f83c8b9e6b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java @@ -114,11 +114,6 @@ public interface NotificationRowContentBinder { public boolean isLowPriority; /** - * Bind child version of content views. - */ - public boolean isChildInGroup; - - /** * Use increased height when binding contracted view. */ public boolean usesIncreasedHeight; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java index d3fec695f012..f26ecc32821d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java @@ -27,7 +27,6 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin */ public final class RowContentBindParams { private boolean mUseLowPriority; - private boolean mUseChildInGroup; private boolean mUseIncreasedHeight; private boolean mUseIncreasedHeadsUpHeight; private boolean mViewsNeedReinflation; @@ -56,20 +55,6 @@ public final class RowContentBindParams { } /** - * Set whether content should use group child version of its content views. - */ - public void setUseChildInGroup(boolean useChildInGroup) { - if (mUseChildInGroup != useChildInGroup) { - mDirtyContentViews |= (FLAG_CONTENT_VIEW_CONTRACTED | FLAG_CONTENT_VIEW_EXPANDED); - } - mUseChildInGroup = useChildInGroup; - } - - public boolean useChildInGroup() { - return mUseChildInGroup; - } - - /** * Set whether content should use an increased height version of its contracted view. */ public void setUseIncreasedCollapsedHeight(boolean useIncreasedHeight) { @@ -163,10 +148,10 @@ public final class RowContentBindParams { @Override public String toString() { return String.format("RowContentBindParams[mContentViews=%x mDirtyContentViews=%x " - + "mUseLowPriority=%b mUseChildInGroup=%b mUseIncreasedHeight=%b " + + "mUseLowPriority=%b mUseIncreasedHeight=%b " + "mUseIncreasedHeadsUpHeight=%b mViewsNeedReinflation=%b]", - mContentViews, mDirtyContentViews, mUseLowPriority, mUseChildInGroup, - mUseIncreasedHeight, mUseIncreasedHeadsUpHeight, mViewsNeedReinflation); + mContentViews, mDirtyContentViews, mUseLowPriority, mUseIncreasedHeight, + mUseIncreasedHeadsUpHeight, mViewsNeedReinflation); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java index c632f3eb22a2..c6f0a135cd34 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java @@ -71,7 +71,6 @@ public class RowContentBindStage extends BindStage<RowContentBindParams> { BindParams bindParams = new BindParams(); bindParams.isLowPriority = params.useLowPriority(); - bindParams.isChildInGroup = params.useChildInGroup(); bindParams.usesIncreasedHeight = params.useIncreasedHeight(); bindParams.usesIncreasedHeadsUpHeight = params.useIncreasedHeadsUpHeight(); boolean forceInflate = params.needsReinflation(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 3ba6954aaa28..9e19c70abf24 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -5722,6 +5722,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd EmptyShadeView view = (EmptyShadeView) LayoutInflater.from(mContext).inflate( R.layout.status_bar_no_notifications, this, false); view.setText(R.string.empty_shade_text); + view.setOnClickListener(v -> { + final boolean showHistory = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0) == 1; + Intent intent = showHistory ? new Intent( + Settings.ACTION_NOTIFICATION_HISTORY) : new Intent( + Settings.ACTION_NOTIFICATION_SETTINGS); + mStatusBar.startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP); + }); setEmptyShadeView(view); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index 53fa2630a9c3..fbe3e9b19248 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -40,7 +40,6 @@ import android.service.notification.NotificationStats; import android.service.notification.StatusBarNotification; import android.text.TextUtils; import android.util.EventLog; -import android.util.Log; import android.view.RemoteAnimationAdapter; import android.view.View; @@ -91,92 +90,119 @@ import dagger.Lazy; */ public class StatusBarNotificationActivityStarter implements NotificationActivityStarter { - private static final String TAG = "NotifActivityStarter"; - protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private final Context mContext; + + private final CommandQueue mCommandQueue; + private final Handler mMainThreadHandler; + private final Handler mBackgroundHandler; + private final Executor mUiBgExecutor; + private final NotificationEntryManager mEntryManager; + private final NotifPipeline mNotifPipeline; + private final NotifCollection mNotifCollection; + private final HeadsUpManagerPhone mHeadsUpManager; + private final ActivityStarter mActivityStarter; + private final IStatusBarService mBarService; + private final StatusBarStateController mStatusBarStateController; + private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; + private final KeyguardManager mKeyguardManager; + private final IDreamManager mDreamManager; + private final BubbleController mBubbleController; private final Lazy<AssistManager> mAssistManagerLazy; - private final NotificationGroupManager mGroupManager; - private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback; private final NotificationRemoteInputManager mRemoteInputManager; + private final NotificationGroupManager mGroupManager; private final NotificationLockscreenUserManager mLockscreenUserManager; private final ShadeController mShadeController; - private final StatusBar mStatusBar; private final KeyguardStateController mKeyguardStateController; - private final ActivityStarter mActivityStarter; - private final NotificationEntryManager mEntryManager; - private final NotifPipeline mNotifPipeline; - private final NotifCollection mNotifCollection; - private final FeatureFlags mFeatureFlags; - private final StatusBarStateController mStatusBarStateController; private final NotificationInterruptStateProvider mNotificationInterruptStateProvider; + private final LockPatternUtils mLockPatternUtils; + private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback; + private final ActivityIntentHelper mActivityIntentHelper; + + private final FeatureFlags mFeatureFlags; private final MetricsLogger mMetricsLogger; - private final Context mContext; - private final NotificationPanelViewController mNotificationPanel; + private final StatusBarNotificationActivityStarterLogger mLogger; + + private final StatusBar mStatusBar; private final NotificationPresenter mPresenter; - private final LockPatternUtils mLockPatternUtils; - private final HeadsUpManagerPhone mHeadsUpManager; - private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; - private final KeyguardManager mKeyguardManager; + private final NotificationPanelViewController mNotificationPanel; private final ActivityLaunchAnimator mActivityLaunchAnimator; - private final IStatusBarService mBarService; - private final CommandQueue mCommandQueue; - private final IDreamManager mDreamManager; - private final Handler mMainThreadHandler; - private final Handler mBackgroundHandler; - private final ActivityIntentHelper mActivityIntentHelper; - private final BubbleController mBubbleController; - private final Executor mUiBgExecutor; private boolean mIsCollapsingToShowActivityOverLockscreen; - private StatusBarNotificationActivityStarter(Context context, CommandQueue commandQueue, - Lazy<AssistManager> assistManagerLazy, NotificationPanelViewController panel, - NotificationPresenter presenter, NotificationEntryManager entryManager, - HeadsUpManagerPhone headsUpManager, ActivityStarter activityStarter, - ActivityLaunchAnimator activityLaunchAnimator, IStatusBarService statusBarService, + private StatusBarNotificationActivityStarter( + Context context, + CommandQueue commandQueue, + Handler mainThreadHandler, + Handler backgroundHandler, + Executor uiBgExecutor, + NotificationEntryManager entryManager, + NotifPipeline notifPipeline, + NotifCollection notifCollection, + HeadsUpManagerPhone headsUpManager, + ActivityStarter activityStarter, + IStatusBarService statusBarService, StatusBarStateController statusBarStateController, StatusBarKeyguardViewManager statusBarKeyguardViewManager, KeyguardManager keyguardManager, - IDreamManager dreamManager, NotificationRemoteInputManager remoteInputManager, - StatusBarRemoteInputCallback remoteInputCallback, NotificationGroupManager groupManager, + IDreamManager dreamManager, + BubbleController bubbleController, + Lazy<AssistManager> assistManagerLazy, + NotificationRemoteInputManager remoteInputManager, + NotificationGroupManager groupManager, NotificationLockscreenUserManager lockscreenUserManager, - ShadeController shadeController, StatusBar statusBar, + ShadeController shadeController, KeyguardStateController keyguardStateController, NotificationInterruptStateProvider notificationInterruptStateProvider, - MetricsLogger metricsLogger, LockPatternUtils lockPatternUtils, - Handler mainThreadHandler, Handler backgroundHandler, Executor uiBgExecutor, - ActivityIntentHelper activityIntentHelper, BubbleController bubbleController, - FeatureFlags featureFlags, NotifPipeline notifPipeline, - NotifCollection notifCollection) { + LockPatternUtils lockPatternUtils, + StatusBarRemoteInputCallback remoteInputCallback, + ActivityIntentHelper activityIntentHelper, + + FeatureFlags featureFlags, + MetricsLogger metricsLogger, + StatusBarNotificationActivityStarterLogger logger, + + StatusBar statusBar, + NotificationPresenter presenter, + NotificationPanelViewController panel, + ActivityLaunchAnimator activityLaunchAnimator) { mContext = context; - mNotificationPanel = panel; - mPresenter = presenter; + mCommandQueue = commandQueue; + mMainThreadHandler = mainThreadHandler; + mBackgroundHandler = backgroundHandler; + mUiBgExecutor = uiBgExecutor; + mEntryManager = entryManager; + mNotifPipeline = notifPipeline; + mNotifCollection = notifCollection; mHeadsUpManager = headsUpManager; - mActivityLaunchAnimator = activityLaunchAnimator; + mActivityStarter = activityStarter; mBarService = statusBarService; - mCommandQueue = commandQueue; + mStatusBarStateController = statusBarStateController; mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mKeyguardManager = keyguardManager; mDreamManager = dreamManager; + mBubbleController = bubbleController; + mAssistManagerLazy = assistManagerLazy; mRemoteInputManager = remoteInputManager; + mGroupManager = groupManager; mLockscreenUserManager = lockscreenUserManager; mShadeController = shadeController; - // TODO: use KeyguardStateController#isOccluded to remove this dependency - mStatusBar = statusBar; mKeyguardStateController = keyguardStateController; - mActivityStarter = activityStarter; - mEntryManager = entryManager; - mStatusBarStateController = statusBarStateController; mNotificationInterruptStateProvider = notificationInterruptStateProvider; - mMetricsLogger = metricsLogger; - mAssistManagerLazy = assistManagerLazy; - mGroupManager = groupManager; mLockPatternUtils = lockPatternUtils; - mBackgroundHandler = backgroundHandler; - mUiBgExecutor = uiBgExecutor; + mStatusBarRemoteInputCallback = remoteInputCallback; + mActivityIntentHelper = activityIntentHelper; + mFeatureFlags = featureFlags; - mNotifPipeline = notifPipeline; - mNotifCollection = notifCollection; + mMetricsLogger = metricsLogger; + mLogger = logger; + + // TODO: use KeyguardStateController#isOccluded to remove this dependency + mStatusBar = statusBar; + mPresenter = presenter; + mNotificationPanel = panel; + mActivityLaunchAnimator = activityLaunchAnimator; + if (!mFeatureFlags.isNewNotifPipelineRenderingEnabled()) { mEntryManager.addNotificationEntryListener(new NotificationEntryListener() { @Override @@ -192,11 +218,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit } }); } - - mStatusBarRemoteInputCallback = remoteInputCallback; - mMainThreadHandler = mainThreadHandler; - mActivityIntentHelper = activityIntentHelper; - mBubbleController = bubbleController; } /** @@ -207,6 +228,8 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit */ @Override public void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row) { + mLogger.logStartingActivityFromClick(sbn.getKey()); + RemoteInputController controller = mRemoteInputManager.getController(); if (controller.isRemoteInputActive(row.getEntry()) && !TextUtils.isEmpty(row.getActiveRemoteInputText())) { @@ -225,7 +248,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit // The only valid case is Bubble notifications. Guard against other cases // entering here. if (intent == null && !isBubble) { - Log.e(TAG, "onNotificationClicked called for non-clickable notification!"); + mLogger.logNonClickableNotification(sbn.getKey()); return; } @@ -258,6 +281,8 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit boolean isActivityIntent, boolean wasOccluded, boolean showOverLockscreen) { + mLogger.logHandleClickAfterKeyguardDismissed(sbn.getKey()); + // TODO: Some of this code may be able to move to NotificationEntryManager. if (mHeadsUpManager != null && mHeadsUpManager.isAlerting(sbn.getKey())) { // Release the HUN notification to the shade. @@ -304,6 +329,8 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit boolean isActivityIntent, boolean wasOccluded, NotificationEntry parentToCancelFinal) { + mLogger.logHandleClickAfterPanelCollapsed(sbn.getKey()); + String notificationKey = sbn.getKey(); try { // The intent we are sending is for the application, which @@ -343,9 +370,11 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit remoteInputText.toString()); } if (isBubble) { + mLogger.logExpandingBubble(notificationKey); expandBubbleStackOnMainThread(notificationKey); } else { - startNotificationIntent(intent, fillInIntent, row, wasOccluded, isActivityIntent); + startNotificationIntent( + intent, fillInIntent, entry, row, wasOccluded, isActivityIntent); } if (isActivityIntent || isBubble) { mAssistManagerLazy.get().hideAssist(); @@ -392,10 +421,16 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit } } - private void startNotificationIntent(PendingIntent intent, Intent fillInIntent, - View row, boolean wasOccluded, boolean isActivityIntent) { + private void startNotificationIntent( + PendingIntent intent, + Intent fillInIntent, + NotificationEntry entry, + View row, + boolean wasOccluded, + boolean isActivityIntent) { RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(row, wasOccluded); + mLogger.logStartNotificationIntent(entry.getKey(), intent); try { if (adapter != null) { ActivityTaskManager.getService() @@ -408,7 +443,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit } catch (RemoteException | PendingIntent.CanceledException e) { // the stack trace isn't very helpful here. // Just log the exception message. - Log.w(TAG, "Sending contentIntent failed: " + e); + mLogger.logSendingIntentFailed(e); // TODO: Dismiss Keyguard. } } @@ -438,13 +473,9 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private void handleFullScreenIntent(NotificationEntry entry) { if (mNotificationInterruptStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) { if (shouldSuppressFullScreenIntent(entry)) { - if (DEBUG) { - Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + entry.getKey()); - } + mLogger.logFullScreenIntentSuppressedByDnD(entry.getKey()); } else if (entry.getImportance() < NotificationManager.IMPORTANCE_HIGH) { - if (DEBUG) { - Log.d(TAG, "No Fullscreen intent: not important enough: " + entry.getKey()); - } + mLogger.logFullScreenIntentNotImportantEnough(entry.getKey()); } else { // Stop screensaver if the notification has a fullscreen intent. // (like an incoming phone call) @@ -457,13 +488,13 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit }); // not immersive & a fullscreen alert should be shown - if (DEBUG) { - Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent"); - } + final PendingIntent fullscreenIntent = + entry.getSbn().getNotification().fullScreenIntent; + mLogger.logSendingFullScreenIntent(entry.getKey(), fullscreenIntent); try { EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION, entry.getKey()); - entry.getSbn().getNotification().fullScreenIntent.send(); + fullscreenIntent.send(); entry.notifyFullScreenIntentLaunched(); mMetricsLogger.count("note_fullscreen", 1); } catch (PendingIntent.CanceledException e) { @@ -578,9 +609,10 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit public static class Builder { private final Context mContext; private final CommandQueue mCommandQueue; - private final Lazy<AssistManager> mAssistManagerLazy; + private final Handler mMainThreadHandler; + private final Handler mBackgroundHandler; + private final Executor mUiBgExecutor; private final NotificationEntryManager mEntryManager; - private final FeatureFlags mFeatureFlags; private final NotifPipeline mNotifPipeline; private final NotifCollection mNotifCollection; private final HeadsUpManagerPhone mHeadsUpManager; @@ -590,30 +622,37 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private final KeyguardManager mKeyguardManager; private final IDreamManager mDreamManager; + private final BubbleController mBubbleController; + private final Lazy<AssistManager> mAssistManagerLazy; private final NotificationRemoteInputManager mRemoteInputManager; - private final StatusBarRemoteInputCallback mRemoteInputCallback; private final NotificationGroupManager mGroupManager; private final NotificationLockscreenUserManager mLockscreenUserManager; + private final ShadeController mShadeController; private final KeyguardStateController mKeyguardStateController; - private final MetricsLogger mMetricsLogger; + private final NotificationInterruptStateProvider mNotificationInterruptStateProvider; private final LockPatternUtils mLockPatternUtils; - private final Handler mMainThreadHandler; - private final Handler mBackgroundHandler; - private final Executor mUiBgExecutor; + private final StatusBarRemoteInputCallback mRemoteInputCallback; private final ActivityIntentHelper mActivityIntentHelper; - private final BubbleController mBubbleController; - private NotificationPanelViewController mNotificationPanelViewController; - private NotificationInterruptStateProvider mNotificationInterruptStateProvider; - private final ShadeController mShadeController; + + private final FeatureFlags mFeatureFlags; + private final MetricsLogger mMetricsLogger; + private final StatusBarNotificationActivityStarterLogger mLogger; + + private StatusBar mStatusBar; private NotificationPresenter mNotificationPresenter; + private NotificationPanelViewController mNotificationPanelViewController; private ActivityLaunchAnimator mActivityLaunchAnimator; - private StatusBar mStatusBar; @Inject - public Builder(Context context, + public Builder( + Context context, CommandQueue commandQueue, - Lazy<AssistManager> assistManagerLazy, + @Main Handler mainThreadHandler, + @Background Handler backgroundHandler, + @UiBackground Executor uiBgExecutor, NotificationEntryManager entryManager, + NotifPipeline notifPipeline, + NotifCollection notifCollection, HeadsUpManagerPhone headsUpManager, ActivityStarter activityStarter, IStatusBarService statusBarService, @@ -621,27 +660,30 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit StatusBarKeyguardViewManager statusBarKeyguardViewManager, KeyguardManager keyguardManager, IDreamManager dreamManager, + BubbleController bubbleController, + Lazy<AssistManager> assistManagerLazy, NotificationRemoteInputManager remoteInputManager, - StatusBarRemoteInputCallback remoteInputCallback, NotificationGroupManager groupManager, NotificationLockscreenUserManager lockscreenUserManager, + ShadeController shadeController, KeyguardStateController keyguardStateController, NotificationInterruptStateProvider notificationInterruptStateProvider, - MetricsLogger metricsLogger, LockPatternUtils lockPatternUtils, - @Main Handler mainThreadHandler, - @Background Handler backgroundHandler, - @UiBackground Executor uiBgExecutor, + StatusBarRemoteInputCallback remoteInputCallback, ActivityIntentHelper activityIntentHelper, - BubbleController bubbleController, - ShadeController shadeController, + FeatureFlags featureFlags, - NotifPipeline notifPipeline, - NotifCollection notifCollection) { + MetricsLogger metricsLogger, + StatusBarNotificationActivityStarterLogger logger) { + mContext = context; mCommandQueue = commandQueue; - mAssistManagerLazy = assistManagerLazy; + mMainThreadHandler = mainThreadHandler; + mBackgroundHandler = backgroundHandler; + mUiBgExecutor = uiBgExecutor; mEntryManager = entryManager; + mNotifPipeline = notifPipeline; + mNotifCollection = notifCollection; mHeadsUpManager = headsUpManager; mActivityStarter = activityStarter; mStatusBarService = statusBarService; @@ -649,23 +691,21 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mKeyguardManager = keyguardManager; mDreamManager = dreamManager; + mBubbleController = bubbleController; + mAssistManagerLazy = assistManagerLazy; mRemoteInputManager = remoteInputManager; - mRemoteInputCallback = remoteInputCallback; mGroupManager = groupManager; mLockscreenUserManager = lockscreenUserManager; + mShadeController = shadeController; mKeyguardStateController = keyguardStateController; mNotificationInterruptStateProvider = notificationInterruptStateProvider; - mMetricsLogger = metricsLogger; mLockPatternUtils = lockPatternUtils; - mMainThreadHandler = mainThreadHandler; - mBackgroundHandler = backgroundHandler; - mUiBgExecutor = uiBgExecutor; + mRemoteInputCallback = remoteInputCallback; mActivityIntentHelper = activityIntentHelper; - mBubbleController = bubbleController; - mShadeController = shadeController; + mFeatureFlags = featureFlags; - mNotifPipeline = notifPipeline; - mNotifCollection = notifCollection; + mMetricsLogger = metricsLogger; + mLogger = logger; } /** Sets the status bar to use as {@link StatusBar}. */ @@ -692,37 +732,42 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit } public StatusBarNotificationActivityStarter build() { - return new StatusBarNotificationActivityStarter(mContext, - mCommandQueue, mAssistManagerLazy, - mNotificationPanelViewController, - mNotificationPresenter, + return new StatusBarNotificationActivityStarter( + mContext, + mCommandQueue, + mMainThreadHandler, + mBackgroundHandler, + mUiBgExecutor, mEntryManager, + mNotifPipeline, + mNotifCollection, mHeadsUpManager, mActivityStarter, - mActivityLaunchAnimator, mStatusBarService, mStatusBarStateController, mStatusBarKeyguardViewManager, mKeyguardManager, mDreamManager, + mBubbleController, + mAssistManagerLazy, mRemoteInputManager, - mRemoteInputCallback, mGroupManager, mLockscreenUserManager, mShadeController, - mStatusBar, mKeyguardStateController, mNotificationInterruptStateProvider, - mMetricsLogger, mLockPatternUtils, - mMainThreadHandler, - mBackgroundHandler, - mUiBgExecutor, + mRemoteInputCallback, mActivityIntentHelper, - mBubbleController, + mFeatureFlags, - mNotifPipeline, - mNotifCollection); + mMetricsLogger, + mLogger, + + mStatusBar, + mNotificationPresenter, + mNotificationPanelViewController, + mActivityLaunchAnimator); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt new file mode 100644 index 000000000000..d118747a0365 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone + +import android.app.PendingIntent +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.LogLevel.DEBUG +import com.android.systemui.log.LogLevel.ERROR +import com.android.systemui.log.LogLevel.INFO +import com.android.systemui.log.LogLevel.WARNING +import com.android.systemui.log.dagger.NotifInteractionLog +import javax.inject.Inject + +class StatusBarNotificationActivityStarterLogger @Inject constructor( + @NotifInteractionLog private val buffer: LogBuffer +) { + fun logStartingActivityFromClick(key: String) { + buffer.log(TAG, DEBUG, { + str1 = key + }, { + "(1/4) onNotificationClicked: $str1" + }) + } + + fun logHandleClickAfterKeyguardDismissed(key: String) { + buffer.log(TAG, DEBUG, { + str1 = key + }, { + "(2/4) handleNotificationClickAfterKeyguardDismissed: $str1" + }) + } + + fun logHandleClickAfterPanelCollapsed(key: String) { + buffer.log(TAG, DEBUG, { + str1 = key + }, { + "(3/4) handleNotificationClickAfterPanelCollapsed: $str1" + }) + } + + fun logStartNotificationIntent(key: String, pendingIntent: PendingIntent) { + buffer.log(TAG, INFO, { + str1 = key + str2 = pendingIntent.intent.toString() + }, { + "(4/4) Starting $str2 for notification $str1" + }) + } + + fun logExpandingBubble(key: String) { + buffer.log(TAG, DEBUG, { + str1 = key + }, { + "Expanding bubble for $str1 (rather than firing intent)" + }) + } + + fun logSendingIntentFailed(e: Exception) { + buffer.log(TAG, WARNING, { + str1 = e.toString() + }, { + "Sending contentIntentFailed: $str1" + }) + } + + fun logNonClickableNotification(key: String) { + buffer.log(TAG, ERROR, { + str1 = key + }, { + "onNotificationClicked called for non-clickable notification! $str1" + }) + } + + fun logFullScreenIntentSuppressedByDnD(key: String) { + buffer.log(TAG, DEBUG, { + str1 = key + }, { + "No Fullscreen intent: suppressed by DND: $str1" + }) + } + + fun logFullScreenIntentNotImportantEnough(key: String) { + buffer.log(TAG, DEBUG, { + str1 = key + }, { + "No Fullscreen intent: not important enough: $str1" + }) + } + + fun logSendingFullScreenIntent(key: String, pendingIntent: PendingIntent) { + buffer.log(TAG, INFO, { + str1 = key + str2 = pendingIntent.intent.toString() + }, { + "Notification $str1 has fullScreenIntent; sending fullScreenIntent $str2" + }) + } +} + +private const val TAG = "NotifActivityStarter" diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java index cc6d607a60cf..8acfbf2b6996 100644 --- a/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java +++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java @@ -137,6 +137,36 @@ public abstract class ConcurrencyModule { } /** + * Provide a Background-Thread Executor by default. + */ + @Provides + @Singleton + public static RepeatableExecutor provideRepeatableExecutor(@Background DelayableExecutor exec) { + return new RepeatableExecutorImpl(exec); + } + + /** + * Provide a Background-Thread Executor. + */ + @Provides + @Singleton + @Background + public static RepeatableExecutor provideBackgroundRepeatableExecutor( + @Background DelayableExecutor exec) { + return new RepeatableExecutorImpl(exec); + } + + /** + * Provide a Main-Thread Executor. + */ + @Provides + @Singleton + @Main + public static RepeatableExecutor provideMainRepeatableExecutor(@Main DelayableExecutor exec) { + return new RepeatableExecutorImpl(exec); + } + + /** * Provide an Executor specifically for running UI operations on a separate thread. * * Keep submitted runnables short and to the point, just as with any other UI code. diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/RepeatableExecutor.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/RepeatableExecutor.java new file mode 100644 index 000000000000..aefdc992e831 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/RepeatableExecutor.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.util.concurrency; + +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; + +/** + * A sub-class of {@link Executor} that allows scheduling commands to execute periodically. + */ +public interface RepeatableExecutor extends Executor { + + /** + * Execute supplied Runnable on the Executors thread after initial delay, and subsequently with + * the given delay between the termination of one execution and the commencement of the next. + * + * Each invocation of the supplied Runnable will be scheduled after the previous invocation + * completes. For example, if you schedule the Runnable with a 60 second delay, and the Runnable + * itself takes 1 second, the effective delay will be 61 seconds between each invocation. + * + * See {@link java.util.concurrent.ScheduledExecutorService#scheduleRepeatedly(Runnable, + * long, long)} + * + * @return A Runnable that, when run, removes the supplied argument from the Executor queue. + */ + default Runnable executeRepeatedly(Runnable r, long initialDelayMillis, long delayMillis) { + return executeRepeatedly(r, initialDelayMillis, delayMillis, TimeUnit.MILLISECONDS); + } + + /** + * Execute supplied Runnable on the Executors thread after initial delay, and subsequently with + * the given delay between the termination of one execution and the commencement of the next.. + * + * See {@link java.util.concurrent.ScheduledExecutorService#scheduleRepeatedly(Runnable, + * long, long)} + * + * @return A Runnable that, when run, removes the supplied argument from the Executor queue. + */ + Runnable executeRepeatedly(Runnable r, long initialDelay, long delay, TimeUnit unit); +} diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/RepeatableExecutorImpl.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/RepeatableExecutorImpl.java new file mode 100644 index 000000000000..c03e10e5c981 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/RepeatableExecutorImpl.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.util.concurrency; + +import java.util.concurrent.TimeUnit; + +/** + * Implementation of {@link RepeatableExecutor} for SystemUI. + */ +class RepeatableExecutorImpl implements RepeatableExecutor { + + private final DelayableExecutor mExecutor; + + RepeatableExecutorImpl(DelayableExecutor executor) { + mExecutor = executor; + } + + @Override + public void execute(Runnable command) { + mExecutor.execute(command); + } + + @Override + public Runnable executeRepeatedly(Runnable r, long initDelay, long delay, TimeUnit unit) { + ExecutionToken token = new ExecutionToken(r, delay, unit); + token.start(initDelay, unit); + return token::cancel; + } + + private class ExecutionToken implements Runnable { + private final Runnable mCommand; + private final long mDelay; + private final TimeUnit mUnit; + private final Object mLock = new Object(); + private Runnable mCancel; + + ExecutionToken(Runnable r, long delay, TimeUnit unit) { + mCommand = r; + mDelay = delay; + mUnit = unit; + } + + @Override + public void run() { + mCommand.run(); + synchronized (mLock) { + if (mCancel != null) { + mCancel = mExecutor.executeDelayed(this, mDelay, mUnit); + } + } + } + + /** Starts execution that will repeat the command until {@link cancel}. */ + public void start(long startDelay, TimeUnit unit) { + synchronized (mLock) { + mCancel = mExecutor.executeDelayed(this, startDelay, unit); + } + } + + /** Cancel repeated execution of command. */ + public void cancel() { + synchronized (mLock) { + if (mCancel != null) { + mCancel.run(); + mCancel = null; + } + } + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt index f6ee46b0303a..e3f25c6b0c72 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt @@ -89,6 +89,7 @@ class ControlsControllerImplTest : SysuiTestCase() { @Captor private lateinit var controlLoadCallbackCaptor: ArgumentCaptor<ControlsBindingController.LoadCallback> + @Captor private lateinit var broadcastReceiverCaptor: ArgumentCaptor<BroadcastReceiver> @Captor @@ -97,6 +98,7 @@ class ControlsControllerImplTest : SysuiTestCase() { private lateinit var delayableExecutor: FakeExecutor private lateinit var controller: ControlsControllerImpl + private lateinit var canceller: DidRunRunnable companion object { fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture() @@ -146,6 +148,9 @@ class ControlsControllerImplTest : SysuiTestCase() { } } + canceller = DidRunRunnable() + `when`(bindingController.bindAndLoad(any(), any())).thenReturn(canceller) + controller = ControlsControllerImpl( wrapper, delayableExecutor, @@ -266,7 +271,7 @@ class ControlsControllerImplTest : SysuiTestCase() { assertTrue(favorites.isEmpty()) assertFalse(data.errorOnLoad) - }) + }, Consumer {}) verify(bindingController).bindAndLoad(eq(TEST_COMPONENT), capture(controlLoadCallbackCaptor)) @@ -301,7 +306,7 @@ class ControlsControllerImplTest : SysuiTestCase() { assertEquals(1, favorites.size) assertEquals(TEST_CONTROL_ID, favorites[0]) assertFalse(data.errorOnLoad) - }) + }, Consumer {}) verify(bindingController).bindAndLoad(eq(TEST_COMPONENT), capture(controlLoadCallbackCaptor)) @@ -332,7 +337,7 @@ class ControlsControllerImplTest : SysuiTestCase() { assertEquals(1, favorites.size) assertEquals(TEST_CONTROL_ID, favorites[0]) assertFalse(data.errorOnLoad) - }) + }, Consumer {}) verify(bindingController).bindAndLoad(eq(TEST_COMPONENT), capture(controlLoadCallbackCaptor)) @@ -363,7 +368,7 @@ class ControlsControllerImplTest : SysuiTestCase() { assertEquals(1, favorites.size) assertEquals(TEST_CONTROL_ID, favorites[0]) assertTrue(data.errorOnLoad) - }) + }, Consumer {}) verify(bindingController).bindAndLoad(eq(TEST_COMPONENT), capture(controlLoadCallbackCaptor)) @@ -377,22 +382,15 @@ class ControlsControllerImplTest : SysuiTestCase() { @Test fun testCancelLoad() { - val canceller = object : Runnable { - var ran = false - override fun run() { - ran = true - } - } - `when`(bindingController.bindAndLoad(any(), any())).thenReturn(canceller) - var loaded = false + var cancelRunnable: Runnable? = null controller.replaceFavoritesForStructure(TEST_STRUCTURE_INFO) delayableExecutor.runAllReady() controller.loadForComponent(TEST_COMPONENT, Consumer { loaded = true - }) + }, Consumer { runnable -> cancelRunnable = runnable }) - controller.cancelLoad() + cancelRunnable?.run() delayableExecutor.runAllReady() assertFalse(loaded) @@ -400,61 +398,47 @@ class ControlsControllerImplTest : SysuiTestCase() { } @Test - fun testCancelLoad_noCancelAfterSuccessfulLoad() { - val canceller = object : Runnable { - var ran = false - override fun run() { - ran = true - } - } - `when`(bindingController.bindAndLoad(any(), any())).thenReturn(canceller) - + fun testCancelLoad_afterSuccessfulLoad() { var loaded = false + var cancelRunnable: Runnable? = null controller.replaceFavoritesForStructure(TEST_STRUCTURE_INFO) delayableExecutor.runAllReady() controller.loadForComponent(TEST_COMPONENT, Consumer { loaded = true - }) + }, Consumer { runnable -> cancelRunnable = runnable }) verify(bindingController).bindAndLoad(eq(TEST_COMPONENT), capture(controlLoadCallbackCaptor)) controlLoadCallbackCaptor.value.accept(emptyList()) - controller.cancelLoad() + cancelRunnable?.run() delayableExecutor.runAllReady() assertTrue(loaded) - assertFalse(canceller.ran) + assertTrue(canceller.ran) } @Test - fun testCancelLoad_noCancelAfterErrorLoad() { - val canceller = object : Runnable { - var ran = false - override fun run() { - ran = true - } - } - `when`(bindingController.bindAndLoad(any(), any())).thenReturn(canceller) - + fun testCancelLoad_afterErrorLoad() { var loaded = false + var cancelRunnable: Runnable? = null controller.replaceFavoritesForStructure(TEST_STRUCTURE_INFO) delayableExecutor.runAllReady() controller.loadForComponent(TEST_COMPONENT, Consumer { loaded = true - }) + }, Consumer { runnable -> cancelRunnable = runnable }) verify(bindingController).bindAndLoad(eq(TEST_COMPONENT), capture(controlLoadCallbackCaptor)) controlLoadCallbackCaptor.value.error("") - controller.cancelLoad() + cancelRunnable?.run() delayableExecutor.runAllReady() assertTrue(loaded) - assertFalse(canceller.ran) + assertTrue(canceller.ran) } @Test @@ -465,7 +449,7 @@ class ControlsControllerImplTest : SysuiTestCase() { val newControlInfo = TEST_CONTROL_INFO.copy(controlTitle = TEST_CONTROL_TITLE_2) val control = statelessBuilderFromInfo(newControlInfo).build() - controller.loadForComponent(TEST_COMPONENT, Consumer {}) + controller.loadForComponent(TEST_COMPONENT, Consumer {}, Consumer {}) verify(bindingController).bindAndLoad(eq(TEST_COMPONENT), capture(controlLoadCallbackCaptor)) @@ -963,3 +947,10 @@ class ControlsControllerImplTest : SysuiTestCase() { assertTrue(controller.getFavoritesForStructure(TEST_COMPONENT_2, TEST_STRUCTURE).isEmpty()) } } + +private class DidRunRunnable() : Runnable { + var ran = false + override fun run() { + ran = true + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java index 9112b654c1cc..9a32b1db2ff3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java @@ -39,6 +39,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dump.DumpManager; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTileView; import com.android.systemui.qs.customize.QSCustomizer; import com.android.systemui.qs.logging.QSLogger; @@ -88,6 +89,8 @@ public class QSPanelTest extends SysuiTestCase { private DelayableExecutor mBackgroundExecutor; @Mock private LocalBluetoothManager mLocalBluetoothManager; + @Mock + private ActivityStarter mActivityStarter; @Before public void setup() throws Exception { @@ -98,7 +101,7 @@ public class QSPanelTest extends SysuiTestCase { mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class); mQsPanel = new QSPanel(mContext, null, mDumpManager, mBroadcastDispatcher, mQSLogger, mForegroundExecutor, mBackgroundExecutor, - mLocalBluetoothManager); + mLocalBluetoothManager, mActivityStarter); // Provides a parent with non-zero size for QSPanel mParentView = new FrameLayout(mContext); mParentView.addView(mQsPanel); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java index 4ac5912d0690..8a8d2272d563 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java @@ -32,6 +32,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.qs.QSTileHost; import com.android.systemui.screenrecord.RecordingController; @@ -49,6 +50,8 @@ public class ScreenRecordTileTest extends SysuiTestCase { @Mock private RecordingController mController; @Mock + private ActivityStarter mActivityStarter; + @Mock private QSTileHost mHost; private TestableLooper mTestableLooper; @@ -61,10 +64,11 @@ public class ScreenRecordTileTest extends SysuiTestCase { mTestableLooper = TestableLooper.get(this); mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper()); mController = mDependency.injectMockDependency(RecordingController.class); + mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class); when(mHost.getContext()).thenReturn(mContext); - mTile = new ScreenRecordTile(mHost, mController); + mTile = new ScreenRecordTile(mHost, mController, mActivityStarter); } // Test that the tile is inactive and labeled correctly when the controller is neither starting @@ -82,7 +86,7 @@ public class ScreenRecordTileTest extends SysuiTestCase { mContext.getString(R.string.quick_settings_screen_record_start))); mTile.handleClick(); - verify(mController, times(1)).launchRecordPrompt(); + verify(mController, times(1)).getPromptIntent(); } // Test that the tile is active and labeled correctly when the controller is starting diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java index fb401778d891..23099d783586 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java @@ -193,7 +193,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { assertThat(mTextView.getText()).isEqualTo( mContext.getResources().getString(R.string.dock_alignment_slow_charging)); assertThat(mTextView.getCurrentTextColor()).isEqualTo( - Utils.getColorError(mContext).getDefaultColor()); + mContext.getColor(R.color.misalignment_text_color)); } @Test @@ -211,7 +211,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { assertThat(mTextView.getText()).isEqualTo( mContext.getResources().getString(R.string.dock_alignment_not_charging)); assertThat(mTextView.getCurrentTextColor()).isEqualTo( - Utils.getColorError(mContext).getDefaultColor()); + mContext.getColor(R.color.misalignment_text_color)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java index e55ea41d94e5..d41b6cfb32c0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java @@ -46,6 +46,7 @@ import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.inflation.LowPriorityInflationHelper; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; @@ -110,7 +111,8 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { mock(BubbleController.class), mock(DynamicPrivacyController.class), mock(ForegroundServiceSectionController.class), - mock(DynamicChildBindController.class)); + mock(DynamicChildBindController.class), + mock(LowPriorityInflationHelper.class)); mViewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java index 855f524db3f8..2894abb8f364 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java @@ -63,6 +63,7 @@ import com.android.systemui.statusbar.notification.NotificationFilter; import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationRankingManager; +import com.android.systemui.statusbar.notification.collection.inflation.LowPriorityInflationHelper; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl; import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; import com.android.systemui.statusbar.notification.icon.IconBuilder; @@ -264,7 +265,8 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { new IconManager( mEntryManager, mock(LauncherApps.class), - new IconBuilder(mContext))); + new IconBuilder(mContext)), + mock(LowPriorityInflationHelper.class)); mEntryManager.setUpWithPresenter(mPresenter); mEntryManager.addNotificationEntryListener(mEntryListener); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java index 96a58e27ed0d..ad3bd711c23f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java @@ -147,30 +147,6 @@ public class RowContentBindStageTest extends SysuiTestCase { } @Test - public void testSetUseGroupInChild() { - // GIVEN a view with all content bound. - RowContentBindParams params = mRowContentBindStage.getStageParams(mEntry); - params.requireContentViews(FLAG_CONTENT_VIEW_ALL); - params.clearDirtyContentViews(); - - // WHEN use group is set and stage executed. - params.setUseChildInGroup(true); - mRowContentBindStage.executeStage(mEntry, mRow, (en) -> { }); - - // THEN binder is called with use group view and contracted/expanded are called to bind. - ArgumentCaptor<BindParams> bindParamsCaptor = ArgumentCaptor.forClass(BindParams.class); - verify(mBinder).bindContent( - eq(mEntry), - any(), - eq(FLAG_CONTENT_VIEW_CONTRACTED | FLAG_CONTENT_VIEW_EXPANDED), - bindParamsCaptor.capture(), - anyBoolean(), - any()); - BindParams usedParams = bindParamsCaptor.getValue(); - assertTrue(usedParams.isChildInGroup); - } - - @Test public void testSetUseIncreasedHeight() { // GIVEN a view with all content bound. RowContentBindParams params = mRowContentBindStage.getStageParams(mEntry); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java index dd28687e749c..1afe132f00a9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java @@ -176,25 +176,43 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); when(mFeatureFlags.isNewNotifPipelineRenderingEnabled()).thenReturn(false); - mNotificationActivityStarter = (new StatusBarNotificationActivityStarter.Builder( - getContext(), mock(CommandQueue.class), () -> mAssistManager, - mEntryManager, mock(HeadsUpManagerPhone.class), - mActivityStarter, mStatusBarService, - mock(StatusBarStateController.class), mStatusBarKeyguardViewManager, - mock(KeyguardManager.class), - mock(IDreamManager.class), mRemoteInputManager, - mock(StatusBarRemoteInputCallback.class), mock(NotificationGroupManager.class), - mock(NotificationLockscreenUserManager.class), - mKeyguardStateController, - mock(NotificationInterruptStateProvider.class), mock(MetricsLogger.class), - mock(LockPatternUtils.class), mHandler, mHandler, mUiBgExecutor, - mActivityIntentHelper, mBubbleController, mShadeController, mFeatureFlags, - mNotifPipeline, mNotifCollection) + mNotificationActivityStarter = + new StatusBarNotificationActivityStarter.Builder( + getContext(), + mock(CommandQueue.class), + mHandler, + mHandler, + mUiBgExecutor, + mEntryManager, + mNotifPipeline, + mNotifCollection, + mock(HeadsUpManagerPhone.class), + mActivityStarter, + mStatusBarService, + mock(StatusBarStateController.class), + mStatusBarKeyguardViewManager, + mock(KeyguardManager.class), + mock(IDreamManager.class), + mBubbleController, + () -> mAssistManager, + mRemoteInputManager, + mock(NotificationGroupManager.class), + mock(NotificationLockscreenUserManager.class), + mShadeController, + mKeyguardStateController, + mock(NotificationInterruptStateProvider.class), + mock(LockPatternUtils.class), + mock(StatusBarRemoteInputCallback.class), + mActivityIntentHelper, + + mFeatureFlags, + mock(MetricsLogger.class), + mock(StatusBarNotificationActivityStarterLogger.class)) .setStatusBar(mStatusBar) - .setNotificationPanelViewController(mock(NotificationPanelViewController.class)) .setNotificationPresenter(mock(NotificationPresenter.class)) - .setActivityLaunchAnimator(mock(ActivityLaunchAnimator.class))) - .build(); + .setNotificationPanelViewController(mock(NotificationPanelViewController.class)) + .setActivityLaunchAnimator(mock(ActivityLaunchAnimator.class)) + .build(); // set up dismissKeyguardThenExecute to synchronously invoke the OnDismissAction arg doAnswer(mCallOnDismiss).when(mActivityStarter).dismissKeyguardThenExecute( diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/RepeatableExecutorTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/RepeatableExecutorTest.java new file mode 100644 index 000000000000..00f37ae6f6cb --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/RepeatableExecutorTest.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.util.concurrency; + +import static com.google.common.truth.Truth.assertThat; + +import android.testing.AndroidTestingRunner; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.util.time.FakeSystemClock; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class RepeatableExecutorTest extends SysuiTestCase { + + private static final int DELAY = 100; + + private FakeSystemClock mFakeClock; + private FakeExecutor mFakeExecutor; + private RepeatableExecutor mExecutor; + private CountingTask mCountingTask; + + @Before + public void setUp() throws Exception { + mFakeClock = new FakeSystemClock(); + mFakeExecutor = new FakeExecutor(mFakeClock); + mCountingTask = new CountingTask(); + mExecutor = new RepeatableExecutorImpl(mFakeExecutor); + } + + /** + * Test FakeExecutor that receives non-delayed items to execute. + */ + @Test + public void testExecute() { + mExecutor.execute(mCountingTask); + mFakeExecutor.runAllReady(); + assertThat(mCountingTask.getCount()).isEqualTo(1); + } + + @Test + public void testRepeats() { + // GIVEN that a command is queued to repeat + mExecutor.executeRepeatedly(mCountingTask, DELAY, DELAY); + // WHEN The clock advances and the task is run + mFakeExecutor.advanceClockToNext(); + mFakeExecutor.runAllReady(); + // THEN another task is queued + assertThat(mCountingTask.getCount()).isEqualTo(1); + assertThat(mFakeExecutor.numPending()).isEqualTo(1); + } + + @Test + public void testNoExecutionBeforeStartDelay() { + // WHEN a command is queued with a start delay + mExecutor.executeRepeatedly(mCountingTask, 2 * DELAY, DELAY); + mFakeExecutor.runAllReady(); + // THEN then it doesn't run immediately + assertThat(mCountingTask.getCount()).isEqualTo(0); + assertThat(mFakeExecutor.numPending()).isEqualTo(1); + } + + @Test + public void testExecuteAfterStartDelay() { + // GIVEN that a command is queued to repeat with a longer start delay + mExecutor.executeRepeatedly(mCountingTask, 2 * DELAY, DELAY); + // WHEN the clock advances the start delay + mFakeClock.advanceTime(2 * DELAY); + mFakeExecutor.runAllReady(); + // THEN the command has run and another task is queued + assertThat(mCountingTask.getCount()).isEqualTo(1); + assertThat(mFakeExecutor.numPending()).isEqualTo(1); + } + + @Test + public void testExecuteWithZeroStartDelay() { + // WHEN a command is queued with no start delay + mExecutor.executeRepeatedly(mCountingTask, 0L, DELAY); + mFakeExecutor.runAllReady(); + // THEN the command has run and another task is queued + assertThat(mCountingTask.getCount()).isEqualTo(1); + assertThat(mFakeExecutor.numPending()).isEqualTo(1); + } + + @Test + public void testAdvanceTimeTwice() { + // GIVEN that a command is queued to repeat + mExecutor.executeRepeatedly(mCountingTask, DELAY, DELAY); + // WHEN the clock advances the time DELAY twice + mFakeClock.advanceTime(DELAY); + mFakeExecutor.runAllReady(); + mFakeClock.advanceTime(DELAY); + mFakeExecutor.runAllReady(); + // THEN the command has run twice and another task is queued + assertThat(mCountingTask.getCount()).isEqualTo(2); + assertThat(mFakeExecutor.numPending()).isEqualTo(1); + } + + @Test + public void testCancel() { + // GIVEN that a scheduled command has been cancelled + Runnable cancel = mExecutor.executeRepeatedly(mCountingTask, DELAY, DELAY); + cancel.run(); + // WHEN the clock advances the time DELAY + mFakeClock.advanceTime(DELAY); + mFakeExecutor.runAllReady(); + // THEN the comamnd has not run and no further tasks are queued + assertThat(mCountingTask.getCount()).isEqualTo(0); + assertThat(mFakeExecutor.numPending()).isEqualTo(0); + } + + @Test + public void testCancelAfterStart() { + // GIVEN that a command has reapeated a few times + Runnable cancel = mExecutor.executeRepeatedly(mCountingTask, DELAY, DELAY); + mFakeClock.advanceTime(DELAY); + mFakeExecutor.runAllReady(); + // WHEN cancelled and time advances + cancel.run(); + // THEN the command has only run the first time + assertThat(mCountingTask.getCount()).isEqualTo(1); + assertThat(mFakeExecutor.numPending()).isEqualTo(0); + } + + /** + * Runnable used for testing that counts the number of times run() is invoked. + */ + private static class CountingTask implements Runnable { + + private int mRunCount; + + @Override + public void run() { + mRunCount++; + } + + /** Gets the run count. */ + public int getCount() { + return mRunCount; + } + } +} diff --git a/packages/Tethering/res/values-af/strings.xml b/packages/Tethering/res/values-af/strings.xml index 1258805378ea..056168b12e89 100644 --- a/packages/Tethering/res/values-af/strings.xml +++ b/packages/Tethering/res/values-af/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Verbinding of Wi-Fi-warmkol aktief"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om op te stel."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Verbinding is gedeaktiveer"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontak jou administrateur vir besonderhede"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Verbinding of warmkol is aktief"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tik om op te stel."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Verbinding is gedeaktiveer"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontak jou administrateur vir besonderhede"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Warmkol- en verbindingstatus"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-am/strings.xml b/packages/Tethering/res/values-am/strings.xml index 9c36192257c0..ac468dd14414 100644 --- a/packages/Tethering/res/values-am/strings.xml +++ b/packages/Tethering/res/values-am/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"መሰካት ወይም ገባሪ ድረስ ነጥብ"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ለማዋቀር መታ ያድርጉ።"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"እንደ ሞደም መሰካት ተሰናክሏል"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"እንደ ሞደም መሰካት ወይም መገናኛ ነጥብ ገባሪ"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"ለማዋቀር መታ ያድርጉ።"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"እንደ ሞደም መሰካት ተሰናክሏል"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"መገናኛ ነጥብ እና እንደ ሞደም የመሰካት ሁኔታ"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ar/strings.xml b/packages/Tethering/res/values-ar/strings.xml index 9f84ce4090c6..7d5bad34da04 100644 --- a/packages/Tethering/res/values-ar/strings.xml +++ b/packages/Tethering/res/values-ar/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"النطاق أو نقطة الاتصال نشطة"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"انقر للإعداد."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"تم إيقاف التوصيل"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"اتصل بالمشرف للحصول على التفاصيل"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"النطاق نشط أو نقطة الاتصال نشطة"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"انقر للإعداد."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"التوصيل متوقف."</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"تواصَل مع المشرف للحصول على التفاصيل."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"حالة نقطة الاتصال والتوصيل"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-as/strings.xml b/packages/Tethering/res/values-as/strings.xml index 8855822e7c8b..091350455ba0 100644 --- a/packages/Tethering/res/values-as/strings.xml +++ b/packages/Tethering/res/values-as/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"টেডাৰিং বা হটস্প\'ট সক্ৰিয় অৱস্থাত আছে"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ছেট আপ কৰিবলৈ টিপক।"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"টেডাৰিং অক্ষম কৰি থোৱা হৈছে"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"সবিশেষ জানিবলৈ আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"টে\'ডাৰিং অথবা হ\'টস্প\'ট সক্ৰিয় অৱস্থাত আছে"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"ছেট আপ কৰিবলৈ টিপক।"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"টে\'ডাৰিঙৰ সুবিধাটো অক্ষম কৰি থোৱা হৈছে"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"সবিশেষ জানিবলৈ আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"হ’টস্প\'ট আৰু টে\'ডাৰিঙৰ স্থিতি"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-az/strings.xml b/packages/Tethering/res/values-az/strings.xml index eba50eb636c1..dce70da178f1 100644 --- a/packages/Tethering/res/values-az/strings.xml +++ b/packages/Tethering/res/values-az/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tezerinq və ya hotspot aktivdir"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Quraşdırmaq üçün tıklayın."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Birləşmə deaktivdir"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Məlumat üçün adminlə əlaqə saxlayın"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Birləşmə və ya hotspot aktivdir"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamaq üçün toxunun."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Birləşmə deaktivdir"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Detallar üçün adminlə əlaqə saxlayın"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot & birləşmə statusu"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-b+sr+Latn/strings.xml b/packages/Tethering/res/values-b+sr+Latn/strings.xml index 5b0e488ba5e6..b0774ec9a840 100644 --- a/packages/Tethering/res/values-b+sr+Latn/strings.xml +++ b/packages/Tethering/res/values-b+sr+Latn/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivno povezivanje sa internetom preko mobilnog uređaja ili hotspot"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste podesili."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Privezivanje je onemogućeno"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Potražite detalje od administratora"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Privezivanje ili hotspot je aktivan"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste podesili."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Privezivanje je onemogućeno"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Potražite detalje od administratora"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspota i privezivanja"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-be/strings.xml b/packages/Tethering/res/values-be/strings.xml index 5966c7155ecd..a8acebe2e992 100644 --- a/packages/Tethering/res/values-be/strings.xml +++ b/packages/Tethering/res/values-be/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"USB-мадэм або хот-спот Wi-Fi актыўныя"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Дакраніцеся, каб наладзіць."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Рэжым мадэма адключаны"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Звярніцеся да адміністратара па падрабязную інфармацыю"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Мадэм або хот-спот актыўныя"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Дакраніцеся, каб наладзіць."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Рэжым мадэма выключаны"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Звярніцеся да адміністратара па падрабязную інфармацыю"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Стан \"Хот-спот і мадэм\""</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-bg/strings.xml b/packages/Tethering/res/values-bg/strings.xml index ed58d7311aca..94fb2d8f176a 100644 --- a/packages/Tethering/res/values-bg/strings.xml +++ b/packages/Tethering/res/values-bg/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Има активна споделена връзка или безжична точка за достъп"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Докоснете, за да настроите."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Функцията за тетъринг е деактивирана"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Свържете се с администратора си за подробности"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Има активна споделена връзка или точка за достъп"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Докоснете, за да настроите."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Функцията за тетъринг е деактивирана"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Свържете се с администратора си за подробности"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Състояние на функцията за точка за достъп и тетъринг"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-bn/strings.xml b/packages/Tethering/res/values-bn/strings.xml index 8d9880aa9aca..aea02b9ddff8 100644 --- a/packages/Tethering/res/values-bn/strings.xml +++ b/packages/Tethering/res/values-bn/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"টিথারিং বা হটস্পট সক্রিয় আছে"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"সেট-আপ করার জন্য আলতো চাপুন৷"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"টিথারিং অক্ষম করা আছে"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"বিশদ বিবরণের জন্য প্রশাসকের সাথে যোগাযোগ করুন"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"টিথারিং বা হটস্পট চালু আছে"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"সেট-আপ করতে ট্যাপ করুন।"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"টিথারিং বন্ধ করা আছে"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"বিশদে জানতে অ্যাডমিনের সাথে যোগাযোগ করুন"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"হটস্পট ও টিথারিং স্ট্যাটাস"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-bs/strings.xml b/packages/Tethering/res/values-bs/strings.xml index 2361b9dd382c..de232724c5d9 100644 --- a/packages/Tethering/res/values-bs/strings.xml +++ b/packages/Tethering/res/values-bs/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Uređaj dijeli vezu ili djeluje kao pristupna tačka"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite za postavke"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezivanje putem mobitela je onemogućeno"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontaktirajte svog administratora za dodatne detalje"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Aktivno je povezivanje putem mobitela ili pristupna tačka"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da postavite."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezivanje putem mobitela je onemogućeno"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontaktirajte svog administratora za detalje"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status pristupne tačke i povezivanja putem mobitela"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ca/strings.xml b/packages/Tethering/res/values-ca/strings.xml index 6752b519e218..88b795c1f8b2 100644 --- a/packages/Tethering/res/values-ca/strings.xml +++ b/packages/Tethering/res/values-ca/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Compartició de xarxa o punt d\'accés Wi-Fi activat"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Toca per configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"La compartició de xarxa està desactivada"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta amb el teu administrador per obtenir més informació"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Compartició de xarxa o punt d\'accés Wi‑Fi actius"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toca per configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"La compartició de xarxa està desactivada"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta amb el teu administrador per obtenir més informació"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estat del punt d\'accés Wi‑Fi i de la compartició de xarxa"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-cs/strings.xml b/packages/Tethering/res/values-cs/strings.xml index 5fdd53adf15c..8c1b83bf3ee3 100644 --- a/packages/Tethering/res/values-cs/strings.xml +++ b/packages/Tethering/res/values-cs/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Sdílené připojení nebo hotspot je aktivní."</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím zahájíte nastavení."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je zakázán"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požádejte administrátora"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering nebo hotspot je aktivní"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím zahájíte nastavení."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je zakázán"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požádejte administrátora"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-da/strings.xml b/packages/Tethering/res/values-da/strings.xml index 2775dfa551cb..f413e7054819 100644 --- a/packages/Tethering/res/values-da/strings.xml +++ b/packages/Tethering/res/values-da/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Netdeling eller hotspot er aktivt"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tryk for at konfigurere"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Netdeling er deaktiveret"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakt din administrator for at få oplysninger"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Netdeling eller hotspot er aktivt"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tryk for at konfigurere."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Netdeling er deaktiveret"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakt din administrator for at få oplysninger"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for hotspot og netdeling"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-de/strings.xml b/packages/Tethering/res/values-de/strings.xml index 9046cd5e1144..f057d7824e81 100644 --- a/packages/Tethering/res/values-de/strings.xml +++ b/packages/Tethering/res/values-de/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oder Hotspot aktiv"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Zum Einrichten tippen."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering ist deaktiviert"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Bitte wende dich für weitere Informationen an den Administrator"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering oder Hotspot aktiv"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Zum Einrichten tippen."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering ist deaktiviert"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Bitte wende dich für weitere Informationen an den Administrator"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot- und Tethering-Status"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-el/strings.xml b/packages/Tethering/res/values-el/strings.xml index 3b9f53733b8a..b3c986bdafd6 100644 --- a/packages/Tethering/res/values-el/strings.xml +++ b/packages/Tethering/res/values-el/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Πατήστε για ρύθμιση."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Η σύνδεση είναι απενεργοποιημένη"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Πατήστε για ρύθμιση."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Η σύνδεση είναι απενεργοποιημένη"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Κατάσταση σημείου πρόσβασης Wi-Fi και σύνδεσης"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-en-rAU/strings.xml b/packages/Tethering/res/values-en-rAU/strings.xml index 56b88a5fb3e1..769e01208afc 100644 --- a/packages/Tethering/res/values-en-rAU/strings.xml +++ b/packages/Tethering/res/values-en-rAU/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-en-rCA/strings.xml b/packages/Tethering/res/values-en-rCA/strings.xml index 56b88a5fb3e1..769e01208afc 100644 --- a/packages/Tethering/res/values-en-rCA/strings.xml +++ b/packages/Tethering/res/values-en-rCA/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-en-rGB/strings.xml b/packages/Tethering/res/values-en-rGB/strings.xml index 56b88a5fb3e1..769e01208afc 100644 --- a/packages/Tethering/res/values-en-rGB/strings.xml +++ b/packages/Tethering/res/values-en-rGB/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-en-rIN/strings.xml b/packages/Tethering/res/values-en-rIN/strings.xml index 56b88a5fb3e1..769e01208afc 100644 --- a/packages/Tethering/res/values-en-rIN/strings.xml +++ b/packages/Tethering/res/values-en-rIN/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-en-rXC/strings.xml b/packages/Tethering/res/values-en-rXC/strings.xml index 7f47fc89d2af..f1674bed4eb7 100644 --- a/packages/Tethering/res/values-en-rXC/strings.xml +++ b/packages/Tethering/res/values-en-rXC/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot & tethering status"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-es-rUS/strings.xml b/packages/Tethering/res/values-es-rUS/strings.xml index e4618b8cec96..63689f43997c 100644 --- a/packages/Tethering/res/values-es-rUS/strings.xml +++ b/packages/Tethering/res/values-es-rUS/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Anclaje a red o zona activa conectados"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Presiona para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Se inhabilitó la conexión mediante dispositivo portátil"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Para obtener más información, comunícate con el administrador"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión a red o hotspot conectados"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Presiona para configurar esta opción."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Se inhabilitó la conexión mediante dispositivo portátil"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Para obtener más información, comunícate con el administrador"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del hotspot y la conexión mediante dispositivo portátil"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-es/strings.xml b/packages/Tethering/res/values-es/strings.xml index 8dc1575ce8ea..9a34ed5e388a 100644 --- a/packages/Tethering/res/values-es/strings.xml +++ b/packages/Tethering/res/values-es/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Compartir conexión/Zona Wi-Fi activada"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Toca para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"La conexión compartida está inhabilitada"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ponte en contacto con el administrador para obtener más información"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida o punto de acceso activos"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"La conexión compartida está inhabilitada"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Solicita más información a tu administrador"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del punto de acceso y de la conexión compartida"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-et/strings.xml b/packages/Tethering/res/values-et/strings.xml index 872c8a74cc59..0970341ab0cd 100644 --- a/packages/Tethering/res/values-et/strings.xml +++ b/packages/Tethering/res/values-et/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Jagamine või kuumkoht on aktiivne"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Puudutage seadistamiseks."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Jagamine on keelatud"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Jagamine või kuumkoht on aktiivne"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Puudutage seadistamiseks."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Jagamine on keelatud"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Kuumkoha ja jagamise olek"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-eu/strings.xml b/packages/Tethering/res/values-eu/strings.xml index 6c4605e616c1..632019e2ef1b 100644 --- a/packages/Tethering/res/values-eu/strings.xml +++ b/packages/Tethering/res/values-eu/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Konexioa partekatzea edo sare publikoa aktibo"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Sakatu konfiguratzeko."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Desgaituta dago konexioa partekatzeko aukera"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Konexioa partekatzea edo wifi-gunea aktibo dago"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Sakatu konfiguratzeko."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Desgaituta dago konexioa partekatzeko aukera"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Wifi-gunearen eta konexioa partekatzeko eginbidearen egoera"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-fa/strings.xml b/packages/Tethering/res/values-fa/strings.xml index bc2ee23609c3..2e21c85fa179 100644 --- a/packages/Tethering/res/values-fa/strings.xml +++ b/packages/Tethering/res/values-fa/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"اشتراکگذاری اینترنت یا نقطه اتصال فعال"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"برای راهاندازی ضربه بزنید."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"اشتراکگذاری اینترنت غیرفعال است"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"برای جزئیات، با سرپرستتان تماس بگیرید"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"اشتراکگذاری اینترنت یا نقطه اتصال فعال"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"برای راهاندازی ضربه بزنید."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"اشتراکگذاری اینترنت غیرفعال است"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"برای جزئیات، با سرپرستتان تماس بگیرید"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"وضعیت نقطه اتصال و اشتراکگذاری اینترنت"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-fi/strings.xml b/packages/Tethering/res/values-fi/strings.xml index ff0fca6502df..413db3f0f8c9 100644 --- a/packages/Tethering/res/values-fi/strings.xml +++ b/packages/Tethering/res/values-fi/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Internetin jakaminen tai yhteyspiste käytössä"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Määritä napauttamalla."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Yhteyden jakaminen poistettu käytöstä"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kysy lisätietoja järjestelmänvalvojalta."</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Yhteyden jakaminen tai hotspot käytössä"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ota käyttöön napauttamalla."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Yhteyden jakaminen on poistettu käytöstä"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pyydä lisätietoja järjestelmänvalvojalta"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspotin ja yhteyden jakamisen tila"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-fr-rCA/strings.xml b/packages/Tethering/res/values-fr-rCA/strings.xml index 1f5df0ee0cb0..eb2e4ba54000 100644 --- a/packages/Tethering/res/values-fr-rCA/strings.xml +++ b/packages/Tethering/res/values-fr-rCA/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Touchez pour configurer."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Communiquez avec votre administrateur pour obtenir plus de détails"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès sans fil activé"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Touchez pour configurer."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Communiquez avec votre administrateur pour obtenir plus de détails"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Point d\'accès et partage de connexion"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-fr/strings.xml b/packages/Tethering/res/values-fr/strings.xml index daf7c9d830d5..22259c52ab9e 100644 --- a/packages/Tethering/res/values-fr/strings.xml +++ b/packages/Tethering/res/values-fr/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Appuyez ici pour configurer."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Pour en savoir plus, contactez votre administrateur"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès activé"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Appuyez pour effectuer la configuration."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pour en savoir plus, contactez votre administrateur"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"État du point d\'accès et du partage de connexion"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-gl/strings.xml b/packages/Tethering/res/values-gl/strings.xml index 0d16a1de094f..ded82fcd54ad 100644 --- a/packages/Tethering/res/values-gl/strings.xml +++ b/packages/Tethering/res/values-gl/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Conexión compartida ou zona wifi activada"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tocar para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"A conexión compartida está desactivada"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta co administrador para obter información"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida ou zona wifi activada"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"A conexión compartida está desactivada"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta co administrador para obter información"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona wifi e da conexión compartida"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-gu/strings.xml b/packages/Tethering/res/values-gu/strings.xml index 9d6b02f85fc9..7cbbc2de3d91 100644 --- a/packages/Tethering/res/values-gu/strings.xml +++ b/packages/Tethering/res/values-gu/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ટિથરિંગ અથવા હૉટસ્પૉટ સક્રિય"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"સેટ કરવા માટે ટૅપ કરો."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ટિથરિંગ અક્ષમ કરેલ છે"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"વિગતો માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ઇન્ટરનેટ શેર કરવાની સુવિધા અથવા હૉટસ્પૉટ સક્રિય છે"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"સેટઅપ કરવા માટે ટૅપ કરો."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરી છે"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"વિગતો માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"હૉટસ્પૉટ અને ઇન્ટરનેટ શેર કરવાની સુવિધાનું સ્ટેટસ"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-hi/strings.xml b/packages/Tethering/res/values-hi/strings.xml index 9c29d9a8f9a1..08af81b826b3 100644 --- a/packages/Tethering/res/values-hi/strings.xml +++ b/packages/Tethering/res/values-hi/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग या हॉटस्पॉट सक्रिय"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करने के लिए टैप करें."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग अक्षम है"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"जानकारी के लिए अपने एडमिन से संपर्क करें"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिंग या हॉटस्पॉट चालू है"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"सेट अप करने के लिए टैप करें."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिंग बंद है"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"जानकारी के लिए अपने एडमिन से संपर्क करें"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हॉटस्पॉट और टेदरिंग की स्थिति"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-hr/strings.xml b/packages/Tethering/res/values-hr/strings.xml index d0d25bb755aa..827c135f205d 100644 --- a/packages/Tethering/res/values-hr/strings.xml +++ b/packages/Tethering/res/values-hr/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Ograničenje ili aktivan hotspot"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste postavili."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modemsko je povezivanje onemogućeno"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Obratite se administratoru da biste saznali pojedinosti"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Modemsko povezivanje ili žarišna točka aktivni"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste postavili."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modemsko je povezivanje onemogućeno"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Obratite se administratoru da biste saznali pojedinosti"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status žarišne točke i modemskog povezivanja"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-hu/strings.xml b/packages/Tethering/res/values-hu/strings.xml index 31296599231e..eb68d6babf8f 100644 --- a/packages/Tethering/res/values-hu/strings.xml +++ b/packages/Tethering/res/values-hu/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Megosztás vagy aktív hotspot"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Koppintson a beállításhoz."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Az internetmegosztás le van tiltva"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"A részletekért forduljon rendszergazdájához"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Megosztás vagy aktív hotspot"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Koppintson a beállításhoz."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Az internetmegosztás le van tiltva"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"A részletekért forduljon rendszergazdájához"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot és internetmegosztás állapota"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-hy/strings.xml b/packages/Tethering/res/values-hy/strings.xml index 8ba6435fd58e..912941e53835 100644 --- a/packages/Tethering/res/values-hy/strings.xml +++ b/packages/Tethering/res/values-hy/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Մոդեմի ռեժիմը միացված է"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Հպեք՝ կարգավորելու համար:"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Մոդեմի ռեժիմն անջատված է"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Մոդեմի ռեժիմը միացված է"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Հպեք՝ կարգավորելու համար։"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Մոդեմի ռեժիմն անջատված է"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Թեժ կետի և մոդեմի ռեժիմի կարգավիճակը"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-in/strings.xml b/packages/Tethering/res/values-in/strings.xml index 1e093ab237e8..a4e175a439e9 100644 --- a/packages/Tethering/res/values-in/strings.xml +++ b/packages/Tethering/res/values-in/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering (Penambatan) atau hotspot aktif"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Ketuk untuk menyiapkan."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering dinonaktifkan"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi admin untuk mengetahui detailnya"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering atau hotspot aktif"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ketuk untuk menyiapkan."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering dinonaktifkan"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi admin untuk mengetahui detailnya"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspot & tethering"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-is/strings.xml b/packages/Tethering/res/values-is/strings.xml index f5769d5344ae..e9f6670bcd09 100644 --- a/packages/Tethering/res/values-is/strings.xml +++ b/packages/Tethering/res/values-is/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Kveikt á tjóðrun eða aðgangsstað"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Ýttu til að setja upp."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Slökkt er á tjóðrun"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Kveikt á tjóðrun eða aðgangsstað"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ýttu til að setja upp."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Slökkt er á tjóðrun"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Staða heits reits og tjóðrunar"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-it/strings.xml b/packages/Tethering/res/values-it/strings.xml index e0b3724325fc..ffb9196f5ee3 100644 --- a/packages/Tethering/res/values-it/strings.xml +++ b/packages/Tethering/res/values-it/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oppure hotspot attivo"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tocca per impostare."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering disattivato"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contatta il tuo amministratore per avere informazioni dettagliate"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Hotspot o tethering attivo"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tocca per impostare."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering disattivato"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contatta il tuo amministratore per avere informazioni dettagliate"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stato hotspot e tethering"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-iw/strings.xml b/packages/Tethering/res/values-iw/strings.xml index c002c44b2361..7adcb47350c1 100644 --- a/packages/Tethering/res/values-iw/strings.xml +++ b/packages/Tethering/res/values-iw/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"שיתוף אינטרנט פעיל"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"הקש כדי להגדיר."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"שיתוף האינטרנט בין ניידים מושבת"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"לפרטים, יש לפנות למנהל המערכת"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"נקודה לשיתוף אינטרנט או שיתוף אינטרנט בין מכשירים: בסטטוס פעיל"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"יש להקיש כדי להגדיר."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"שיתוף האינטרנט בין מכשירים מושבת"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"לפרטים, יש לפנות למנהל המערכת"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"סטטוס של נקודה לשיתוף אינטרנט ושיתוף אינטרנט בין מכשירים"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ja/strings.xml b/packages/Tethering/res/values-ja/strings.xml index 314bde00df02..f68a73010b36 100644 --- a/packages/Tethering/res/values-ja/strings.xml +++ b/packages/Tethering/res/values-ja/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"タップしてセットアップします。"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"テザリングは無効に設定されています"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳しくは、管理者にお問い合わせください"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"テザリングまたはアクセス ポイントが有効です"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"タップしてセットアップします。"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"テザリングは無効に設定されています"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳しくは、管理者にお問い合わせください"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"アクセス ポイントとテザリングのステータス"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ka/strings.xml b/packages/Tethering/res/values-ka/strings.xml index 7bbd81d3435a..7c22e82bd370 100644 --- a/packages/Tethering/res/values-ka/strings.xml +++ b/packages/Tethering/res/values-ka/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"შეეხეთ დასაყენებლად."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ტეტერინგი გათიშულია"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"შეეხეთ დასაყენებლად."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ტეტერინგი გათიშულია"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"უსადენო ქსელის და ტეტერინგის სტატუსი"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-kk/strings.xml b/packages/Tethering/res/values-kk/strings.xml index 7fd87a159657..0857d06de243 100644 --- a/packages/Tethering/res/values-kk/strings.xml +++ b/packages/Tethering/res/values-kk/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Тетеринг немесе хотспот қосулы"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Реттеу үшін түртіңіз."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Тетеринг өшірілді"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Мәліметтерді әкімшіден алыңыз"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Тетеринг немесе хотспот қосулы"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Реттеу үшін түртіңіз."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Тетеринг өшірілді."</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Мәліметтерді әкімшіден алыңыз."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Хотспот және тетеринг күйі"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-km/strings.xml b/packages/Tethering/res/values-km/strings.xml index 2f852246790c..536e3d1703b1 100644 --- a/packages/Tethering/res/values-km/strings.xml +++ b/packages/Tethering/res/values-km/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬហតស្ពតសកម្ម"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ប៉ះដើម្បីកំណត់"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ការភ្ជាប់ត្រូវបានបិទ"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ទាក់ទងអ្នកគ្រប់គ្រងរបស់អ្នកសម្រាប់ព័ត៌មានលម្អិត"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ការភ្ជាប់ ឬហតស្ប៉តកំពុងដំណើរការ"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"ចុចដើម្បីរៀបចំ។"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ការភ្ជាប់ត្រូវបានបិទ"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"ទាក់ទងអ្នកគ្រប់គ្រងរបស់អ្នក ដើម្បីទទួលបានព័ត៌មានលម្អិត"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ស្ថានភាពនៃការភ្ជាប់ និងហតស្ប៉ត"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-kn/strings.xml b/packages/Tethering/res/values-kn/strings.xml index f11a83ea40ee..32f54926f4bf 100644 --- a/packages/Tethering/res/values-kn/strings.xml +++ b/packages/Tethering/res/values-kn/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ಟೆಥರಿಂಗ್ ಅಥವಾ ಹಾಟ್ಸ್ಪಾಟ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ಟೆಥರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ಟೆಥರಿಂಗ್ ಅಥವಾ ಹಾಟ್ಸ್ಪಾಟ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"ಸೆಟಪ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ಟೆಥರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ಹಾಟ್ಸ್ಪಾಟ್ ಮತ್ತು ಟೆಥರಿಂಗ್ ಸ್ಥಿತಿ"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ko/strings.xml b/packages/Tethering/res/values-ko/strings.xml index 57f24f5b1ae2..156b24786db5 100644 --- a/packages/Tethering/res/values-ko/strings.xml +++ b/packages/Tethering/res/values-ko/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"테더링 또는 핫스팟 사용"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"설정하려면 탭하세요."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"테더링이 사용 중지됨"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"자세한 정보는 관리자에게 문의하세요."</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"테더링 또는 핫스팟 사용"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"설정하려면 탭하세요."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"테더링이 사용 중지됨"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"자세한 정보는 관리자에게 문의하세요."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"핫스팟 및 테더링 상태"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ky/strings.xml b/packages/Tethering/res/values-ky/strings.xml index 79854859d41e..18ee5fd35718 100644 --- a/packages/Tethering/res/values-ky/strings.xml +++ b/packages/Tethering/res/values-ky/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Жалгаштыруу же хотспот жандырылган"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Жөндөө үчүн таптап коюңуз."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Жалгаштыруу функциясы өчүрүлгөн"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Модем режими күйүп турат"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Жөндөө үчүн таптап коюңуз."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Телефонду модем катары колдонууга болбойт"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Байланыш түйүнүнүн жана модем режиминин статусу"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-lo/strings.xml b/packages/Tethering/res/values-lo/strings.xml index 78f1585f60f7..b12767018c3a 100644 --- a/packages/Tethering/res/values-lo/strings.xml +++ b/packages/Tethering/res/values-lo/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ເປີດການປ່ອຍສັນຍານ ຫຼືຮັອດສະປອດແລ້ວ"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ແຕະເພື່ອຕັ້ງຄ່າ."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ເປີດການປ່ອຍສັນຍານ ຫຼື ຮັອດສະປອດແລ້ວ"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"ແຕະເພື່ອຕັ້ງຄ່າ."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ສະຖານະຮັອດສະປອດ ແລະ ການປ່ອຍສັນຍານ"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-lt/strings.xml b/packages/Tethering/res/values-lt/strings.xml index ebff8ac9d1f1..8427baf39f31 100644 --- a/packages/Tethering/res/values-lt/strings.xml +++ b/packages/Tethering/res/values-lt/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Susietas ar aktyvus"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Palieskite, kad nustatytumėte."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Įrenginio kaip modemo naudojimas išjungtas"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Įrenginys naudojamas kaip modemas arba įjungtas viešosios interneto prieigos taškas"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Palieskite, kad nustatytumėte."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Įrenginio kaip modemo naudojimas išjungtas"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Viešosios interneto prieigos taško ir įrenginio kaip modemo naudojimo būsena"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-lv/strings.xml b/packages/Tethering/res/values-lv/strings.xml index 54d0048b526a..aa2d6990e04f 100644 --- a/packages/Tethering/res/values-lv/strings.xml +++ b/packages/Tethering/res/values-lv/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Piesaiste vai tīklājs ir aktīvs."</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Pieskarieties, lai iestatītu."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Piesaiste ir atspējota"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Piesaiste vai tīklājs ir aktīvs."</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Pieskarieties, lai to iestatītu."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Piesaiste ir atspējota"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Tīklāja un piesaistes statuss"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-af/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-af/strings.xml new file mode 100644 index 000000000000..19d659c6ce36 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-af/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Verbinding het nie internet nie"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Toestelle kan nie koppel nie"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Skakel verbinding af"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Warmkol of verbinding is aan"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Bykomende heffings kan geld terwyl jy swerf"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-am/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-am/strings.xml new file mode 100644 index 000000000000..8995430b4f09 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-am/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ማስተሳሰር ምንም በይነመረብ የለውም"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"መሣሪያዎችን ማገናኘት አይቻልም"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ማስተሳሰርን አጥፋ"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"መገናኛ ነጥብ ወይም ማስተሳሰር በርቷል"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"በሚያንዣብብበት ጊዜ ተጨማሪ ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ar/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ar/strings.xml new file mode 100644 index 000000000000..54f3b5389ae9 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ar/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ما مِن اتصال بالإنترنت خلال التوصيل"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"تعذّر اتصال الأجهزة"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"إيقاف التوصيل"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"نقطة الاتصال أو التوصيل مفعّلان"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"قد يتم تطبيق رسوم إضافية أثناء التجوال."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-as/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-as/strings.xml new file mode 100644 index 000000000000..e215141c9eb6 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-as/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"টে\'ডাৰিঙৰ ইণ্টাৰনেট নাই"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"ডিভাইচসমূহ সংযোগ কৰিব নোৱাৰি"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"টে\'ডাৰিং অফ কৰক"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"হটস্পট অথবা টে\'ডাৰিং অন আছে"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ৰ\'মিঙত থাকিলে অতিৰিক্ত মাচুল প্ৰযোজ্য হ’ব পাৰে"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-az/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-az/strings.xml new file mode 100644 index 000000000000..1fd8e4c963a7 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-az/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modemin internetə girişi yoxdur"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Cihazları qoşmaq mümkün deyil"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Modemi deaktiv edin"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot və ya modem aktivdir"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rouminq zamanı əlavə ödənişlər tətbiq edilə bilər"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml new file mode 100644 index 000000000000..1abe4f3aa3c7 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Privezivanje nema pristup internetu"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Povezivanje uređaja nije uspelo"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključi privezivanje"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Uključen je hotspot ili privezivanje"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Možda važe dodatni troškovi u romingu"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-be/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-be/strings.xml new file mode 100644 index 000000000000..38dbd1e3914f --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-be/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Рэжым мадэма выкарыстоўваецца без доступу да інтэрнэту"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Не ўдалося падключыць прылады"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Выключыць рэжым мадэма"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Хот-спот або рэжым мадэма ўключаны"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Пры выкарыстанні роўмінгу можа спаганяцца дадатковая плата"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-bg/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-bg/strings.xml new file mode 100644 index 000000000000..04b44db5c1a4 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-bg/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Тетърингът няма връзка с интернет"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Устройствата не могат да установят връзка"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Изключване на тетъринга"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Точката за достъп или тетърингът са включени"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Възможно е да ви бъдат начислени допълнителни такси при роуминг"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-bn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-bn/strings.xml new file mode 100644 index 000000000000..579d1be1c1ea --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-bn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"টিথারিং করার জন্য কোনও ইন্টারনেট কানেকশন নেই"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"ডিভাইস কানেক্ট করতে পারছে না"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"টিথারিং বন্ধ করুন"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"হটস্পট বা টিথারিং চালু আছে"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"রোমিংয়ের সময় অতিরিক্ত চার্জ করা হতে পারে"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-bs/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-bs/strings.xml new file mode 100644 index 000000000000..9ce3efe6c39d --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-bs/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Povezivanje putem mobitela nema internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Uređaji se ne mogu povezati"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključi povezivanje putem mobitela"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Pristupna tačka ili povezivanje putem mobitela je uključeno"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Mogu nastati dodatni troškovi u romingu"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ca/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ca/strings.xml new file mode 100644 index 000000000000..46d4c35b9b83 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ca/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"La compartició de xarxa no té accés a Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"No es poden connectar els dispositius"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactiva la compartició de xarxa"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"S\'ha activat el punt d\'accés Wi‑Fi o la compartició de xarxa"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"És possible que s\'apliquin costos addicionals en itinerància"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-cs/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-cs/strings.xml new file mode 100644 index 000000000000..cc13860b3da1 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-cs/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nemá připojení k internetu"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Zařízení se nemůžou připojit"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vypnout tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Je zapnutý hotspot nebo tethering"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Při roamingu mohou být účtovány dodatečné poplatky"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-da/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-da/strings.xml new file mode 100644 index 000000000000..92c3ae11567d --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-da/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Netdeling har ingen internetforbindelse"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enheder kan ikke oprette forbindelse"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Deaktiver netdeling"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot eller netdeling er aktiveret"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Der opkræves muligvis yderligere gebyrer ved roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-de/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-de/strings.xml new file mode 100644 index 000000000000..967eb4db2e77 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-de/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering hat keinen Internetzugriff"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Geräte können sich nicht verbinden"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering deaktivieren"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot oder Tethering ist aktiviert"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Für das Roaming können zusätzliche Gebühren anfallen"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-el/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-el/strings.xml new file mode 100644 index 000000000000..5fb497451f6d --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-el/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Η σύνδεση δεν έχει πρόσβαση στο διαδίκτυο"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Δεν είναι δυνατή η σύνδεση των συσκευών"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Απενεργοποιήστε τη σύνδεση"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ενεργό σημείο πρόσβασης Wi-Fi ή ενεργή σύνδεση"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ενδέχεται να ισχύουν επιπλέον χρεώσεις κατά την περιαγωγή."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml new file mode 100644 index 000000000000..45647f93f246 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml new file mode 100644 index 000000000000..45647f93f246 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml new file mode 100644 index 000000000000..45647f93f246 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml new file mode 100644 index 000000000000..45647f93f246 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml new file mode 100644 index 000000000000..7877074afc66 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml new file mode 100644 index 000000000000..08edd81a6b04 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"La conexión mediante dispositivo móvil no tiene Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"No se pueden conectar los dispositivos"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión mediante dispositivo móvil"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Se activó el hotspot o la conexión mediante dispositivo móvil"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Es posible que se apliquen cargos adicionales por roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-es/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-es/strings.xml new file mode 100644 index 000000000000..79f51d00e2e8 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-es/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"La conexión no se puede compartir, porque no hay acceso a Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Los dispositivos no se pueden conectar"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión compartida"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Punto de acceso o conexión compartida activados"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Puede que se apliquen cargos adicionales en itinerancia"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-et/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-et/strings.xml new file mode 100644 index 000000000000..2da5f8a6d62a --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-et/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Jagamisel puudub internetiühendus"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Seadmed ei saa ühendust luua"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Lülita jagamine välja"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Kuumkoht või jagamine on sisse lülitatud"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rändluse kasutamisega võivad kaasneda lisatasud"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-eu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-eu/strings.xml new file mode 100644 index 000000000000..2073f2806c18 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-eu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Konexioa partekatzeko aukerak ez du Interneteko konexiorik"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Ezin dira konektatu gailuak"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desaktibatu konexioa partekatzeko aukera"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Wifi-gunea edo konexioa partekatzeko aukera aktibatuta dago"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Baliteke kostu gehigarriak ordaindu behar izatea ibiltaritzan"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-fa/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fa/strings.xml new file mode 100644 index 000000000000..e21b2a0852c7 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-fa/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"«اشتراکگذاری اینترنت» به اینترنت دسترسی ندارد"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"دستگاهها متصل نمیشوند"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"خاموش کردن «اشتراکگذاری اینترنت»"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"«نقطه اتصال» یا «اشتراکگذاری اینترنت» روشن است"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ممکن است درحین فراگردی تغییرات دیگر اعمال شود"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-fi/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fi/strings.xml new file mode 100644 index 000000000000..88b0b13eb4b5 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-fi/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ei jaettavaa internetyhteyttä"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Laitteet eivät voi muodostaa yhteyttä"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Laita yhteyden jakaminen pois päältä"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot tai yhteyden jakaminen on päällä"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Roaming voi aiheuttaa lisämaksuja"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml new file mode 100644 index 000000000000..3b781bc8db31 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Le partage de connexion n\'est pas connecté à Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossible de connecter les appareils"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Désactiver le partage de connexion"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Le point d\'accès ou le partage de connexion est activé"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-fr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fr/strings.xml new file mode 100644 index 000000000000..51d7203c3652 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-fr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Aucune connexion à Internet n\'est disponible pour le partage de connexion"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossible de connecter les appareils"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Désactiver le partage de connexion"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Le point d\'accès ou le partage de connexion est activé"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-gl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-gl/strings.xml new file mode 100644 index 000000000000..008ccb475d66 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-gl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"A conexión compartida non ten Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Non se puideron conectar os dispositivos"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión compartida"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Está activada a zona wifi ou a conexión compartida"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pódense aplicar cargos adicionais en itinerancia"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-gu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-gu/strings.xml new file mode 100644 index 000000000000..f2e3b4df782f --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-gu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ઇન્ટરનેટ શેર કરવાની સુવિધામાં ઇન્ટરનેટ નથી"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"ડિવાઇસ કનેક્ટ કરી શકાતા નથી"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરો"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"હૉટસ્પૉટ અથવા ઇન્ટરનેટ શેર કરવાની સુવિધા ચાલુ છે"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"રોમિંગમાં વધારાના શુલ્ક લાગી શકે છે"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-hi/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hi/strings.xml new file mode 100644 index 000000000000..b11839d760c8 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-hi/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिंग से इंटरनेट नहीं चल रहा"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"डिवाइस कनेक्ट नहीं हो पा रहे"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिंग बंद करें"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हॉटस्पॉट या टेदरिंग चालू है"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिंग के दौरान अतिरिक्त शुल्क लग सकता है"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-hr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hr/strings.xml new file mode 100644 index 000000000000..0a5aca25b1a9 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-hr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modemsko povezivanje nema internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Uređaji se ne mogu povezati"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključivanje modemskog povezivanja"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Uključena je žarišna točka ili modemsko povezivanje"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"U roamingu su mogući dodatni troškovi"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-hu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hu/strings.xml new file mode 100644 index 000000000000..21c689a44ef8 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-hu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nincs internetkapcsolat az internet megosztásához"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Az eszközök nem tudnak csatlakozni"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Internetmegosztás kikapcsolása"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"A hotspot vagy az internetmegosztás be van kapcsolva"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Roaming során további díjak léphetnek fel"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-hy/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hy/strings.xml new file mode 100644 index 000000000000..689d92870e50 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-hy/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Մոդեմի ռեժիմի կապը բացակայում է"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Չհաջողվեց միացնել սարքը"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Անջատել մոդեմի ռեժիմը"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Թեժ կետը կամ մոդեմի ռեժիմը միացված է"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ռոումինգում կարող են լրացուցիչ վճարներ գանձվել"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-in/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-in/strings.xml new file mode 100644 index 000000000000..a5f4d19abfe9 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-in/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tidak ada koneksi internet di tethering"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Perangkat tidak dapat terhubung"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Nonaktifkan tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot atau tethering aktif"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Biaya tambahan mungkin berlaku saat roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-is/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-is/strings.xml new file mode 100644 index 000000000000..fc7e8aaf4e42 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-is/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tjóðrun er ekki með internettengingu"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Tæki geta ekki tengst"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Slökkva á tjóðrun"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Kveikt er á heitum reit eða tjóðrun"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Viðbótargjöld kunna að eiga við í reiki"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-it/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-it/strings.xml new file mode 100644 index 000000000000..6456dd1b806a --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-it/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nessuna connessione a Internet per il tethering"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossibile connettere i dispositivi"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Disattiva il tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot o tethering attivi"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Potrebbero essere applicati costi aggiuntivi durante il roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-iw/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-iw/strings.xml new file mode 100644 index 000000000000..46b24bd3c508 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-iw/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"אי אפשר להפעיל את תכונת שיתוף האינטרנט בין מכשירים כי אין חיבור לאינטרנט"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"למכשירים אין אפשרות להתחבר"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"השבתה של שיתוף האינטרנט בין מכשירים"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"תכונת הנקודה לשיתוף אינטרנט או תכונת שיתוף האינטרנט בין מכשירים פועלת"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ייתכנו חיובים נוספים בעת נדידה"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ja/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ja/strings.xml new file mode 100644 index 000000000000..e6eb277b90dd --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ja/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"テザリングがインターネットに接続されていません"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"デバイスを接続できません"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"テザリングを OFF にする"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"アクセス ポイントまたはテザリングが ON です"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ローミング時に追加料金が発生することがあります"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ka/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ka/strings.xml new file mode 100644 index 000000000000..aeddd7101da0 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ka/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ტეტერინგს არ აქვს ინტერნეტზე წვდომა"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"მოწყობილობები ვერ ახერხებენ დაკავშირებას"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ტეტერინგის გამორთვა"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ჩართულია უსადენო ქსელი ან ტეტერინგი"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"როუმინგის გამოყენებისას შეიძლება ჩამოგეჭრათ დამატებითი საფასური"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-kk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-kk/strings.xml new file mode 100644 index 000000000000..255f0a276f95 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-kk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Тетеринг режимі интернет байланысынсыз пайдаланылуда"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Құрылғыларды байланыстыру мүмкін емес"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Тетерингіні өшіру"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Хотспот немесе тетеринг қосулы"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роуминг кезінде қосымша ақы алынуы мүмкін."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-km/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-km/strings.xml new file mode 100644 index 000000000000..2bceb1cf7788 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-km/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ការភ្ជាប់មិនមានអ៊ីនធឺណិតទេ"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"មិនអាចភ្ជាប់ឧបករណ៍បានទេ"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"បិទការភ្ជាប់"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ហតស្ប៉ត ឬការភ្ជាប់ត្រូវបានបើក"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"អាចមានការគិតថ្លៃបន្ថែម នៅពេលរ៉ូមីង"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-kn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-kn/strings.xml new file mode 100644 index 000000000000..ed769305a679 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-kn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ಟೆಥರಿಂಗ್ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಕನೆಕ್ಷನ್ ಹೊಂದಿಲ್ಲ"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"ಸಾಧನಗಳನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ಟೆಥರಿಂಗ್ ಆಫ್ ಮಾಡಿ"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ಹಾಟ್ಸ್ಪಾಟ್ ಅಥವಾ ಟೆಥರಿಂಗ್ ಆನ್ ಆಗಿದೆ"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ರೋಮಿಂಗ್ನಲ್ಲಿರುವಾಗ ಹೆಚ್ಚುವರಿ ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ko/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ko/strings.xml new file mode 100644 index 000000000000..6e504941eb8b --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ko/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"테더링으로 인터넷을 사용할 수 없음"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"기기에서 연결할 수 없음"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"테더링 사용 중지"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"핫스팟 또는 테더링 켜짐"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"로밍 중에는 추가 요금이 발생할 수 있습니다."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ky/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ky/strings.xml new file mode 100644 index 000000000000..d68128b9a554 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ky/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Модем режими Интернети жок колдонулууда"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Түзмөктөр туташпай жатат"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Модем режимин өчүрүү"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Байланыш түйүнү же модем режими күйүк"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роумингде кошумча акы алынышы мүмкүн"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-lo/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-lo/strings.xml new file mode 100644 index 000000000000..03e134a0fc79 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-lo/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ການປ່ອຍສັນຍານບໍ່ມີອິນເຕີເນັດ"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"ອຸປະກອນບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ປິດການປ່ອຍສັນຍານ"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ເປີດໃຊ້ຮັອດສະປອດ ຫຼື ການປ່ອຍສັນຍານຢູ່"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ອາດມີຄ່າໃຊ້ຈ່າຍເພີ່ມເຕີມໃນລະຫວ່າງການໂຣມມິງ"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-lt/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-lt/strings.xml new file mode 100644 index 000000000000..652cedc6e6ae --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-lt/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nėra įrenginio kaip modemo naudojimo interneto ryšio"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Nepavyko susieti įrenginių"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Išjungti įrenginio kaip modemo naudojimą"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Įjungtas viešosios interneto prieigos taškas arba įrenginio kaip modemo naudojimas"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Veikiant tarptinkliniam ryšiui gali būti taikomi papildomi mokesčiai"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-lv/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-lv/strings.xml new file mode 100644 index 000000000000..221972298c18 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-lv/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Piesaistei nav interneta savienojuma"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Nevar savienot ierīces"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Izslēgt piesaisti"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ir ieslēgts tīklājs vai piesaiste"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Viesabonēšanas laikā var tikt piemērota papildu samaksa"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-mk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-mk/strings.xml new file mode 100644 index 000000000000..227f9e346651 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-mk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Нема интернет преку мобилен"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Уредите не може да се поврзат"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Исклучи интернет преку мобилен"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Точката на пристап или интернетот преку мобилен е вклучен"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"При роаминг може да се наплатат дополнителни трошоци"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ml/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ml/strings.xml new file mode 100644 index 000000000000..ec4388512645 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ml/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ടെതറിംഗിന് ഇന്റർനെറ്റ് ഇല്ല"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"ഉപകരണങ്ങൾ കണക്റ്റ് ചെയ്യാനാവില്ല"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ടെതറിംഗ് ഓഫാക്കുക"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ഹോട്ട്സ്പോട്ട് അല്ലെങ്കിൽ ടെതറിംഗ് ഓണാണ്"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"റോമിംഗ് ചെയ്യുമ്പോൾ അധിക നിരക്കുകൾ ബാധകമായേക്കാം"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-mn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-mn/strings.xml new file mode 100644 index 000000000000..e263573799ed --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-mn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Модемд интернэт алга байна"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Төхөөрөмжүүд холбогдох боломжгүй байна"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Модем болгохыг унтраах"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Сүлжээний цэг эсвэл модем болгох асаалттай байна"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роумингийн үеэр нэмэлт төлбөр нэхэмжилж болзошгүй"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-mr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-mr/strings.xml new file mode 100644 index 000000000000..adf845d078bf --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-mr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिंगला इंटरनेट नाही"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"डिव्हाइस कनेक्ट होऊ शकत नाहीत"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिंग बंद करा"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हॉटस्पॉट किंवा टेदरिंग सुरू आहे"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिंगदरम्यान अतिरिक्त शुल्क लागू होऊ शकतात"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ms/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ms/strings.xml new file mode 100644 index 000000000000..f65c451e4c21 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ms/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Penambatan tiada Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Peranti tidak dapat disambungkan"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Matikan penambatan"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Tempat liputan atau penambatan dihidupkan"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Caj tambahan mungkin digunakan semasa perayauan"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-my/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-my/strings.xml new file mode 100644 index 000000000000..4118e775cd84 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-my/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းတွင် အင်တာနက် မရှိပါ"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"စက်များ ချိတ်ဆက်၍ မရပါ"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ပိတ်ရန်"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ဟော့စပေါ့ (သို့) မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ဖွင့်ထားသည်"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ပြင်ပကွန်ရက်နှင့် ချိတ်ဆက်သည့်အခါ နောက်ထပ်ကျသင့်မှုများ ရှိနိုင်သည်"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-nb/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-nb/strings.xml new file mode 100644 index 000000000000..36853583ce82 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-nb/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Internettdeling har ikke internettilgang"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enhetene kan ikke koble til"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Slå av internettdeling"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Wi-Fi-sone eller internettdeling er på"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ytterligere kostnader kan påløpe under roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml new file mode 100644 index 000000000000..2a7330098faf --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- no translation found for no_upstream_notification_title (5030042590486713460) --> + <skip /> + <!-- no translation found for no_upstream_notification_message (3843613362272973447) --> + <skip /> + <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) --> + <skip /> + <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) --> + <skip /> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-nl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-nl/strings.xml new file mode 100644 index 000000000000..1d888942f49b --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-nl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering heeft geen internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Apparaten kunnen niet worden verbonden"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering uitschakelen"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot of tethering is ingeschakeld"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Er kunnen extra kosten voor roaming in rekening worden gebracht."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-or/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-or/strings.xml new file mode 100644 index 000000000000..8038815fe804 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-or/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ଟିଥରିଂ ପାଇଁ କୌଣସି ଇଣ୍ଟର୍ନେଟ୍ ସଂଯୋଗ ନାହିଁ"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"ଡିଭାଇସଗୁଡ଼ିକ ସଂଯୋଗ କରାଯାଇପାରିବ ନାହିଁ"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ଟିଥରିଂ ବନ୍ଦ କରନ୍ତୁ"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ହଟସ୍ପଟ୍ କିମ୍ବା ଟିଥରିଂ ଚାଲୁ ଅଛି"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ରୋମିଂରେ ଥିବା ସମୟରେ ଅତିରିକ୍ତ ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-pa/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pa/strings.xml new file mode 100644 index 000000000000..819833eab07f --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-pa/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ਟੈਦਰਿੰਗ ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"ਡੀਵਾਈਸ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ਟੈਦਰਿੰਗ ਬੰਦ ਕਰੋ"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ਹੌਟਸਪੌਟ ਜਾਂ ਟੈਦਰਿੰਗ ਚਾਲੂ ਹੈ"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ਰੋਮਿੰਗ ਦੌਰਾਨ ਵਧੀਕ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-pl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pl/strings.xml new file mode 100644 index 000000000000..65e4380e3916 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-pl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nie ma internetu"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Urządzenia nie mogą się połączyć"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Wyłącz tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot lub tethering jest włączony"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Podczas korzystania z roamingu mogą zostać naliczone dodatkowe opłaty"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml new file mode 100644 index 000000000000..d8866170c191 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"O tethering não tem Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível conectar os dispositivos"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar o tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ponto de acesso ou tethering ativado"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pode haver cobranças extras durante o roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml new file mode 100644 index 000000000000..bfd45ca0a3e1 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"A ligação (à Internet) via telemóvel não tem Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível ligar os dispositivos"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar ligação (à Internet) via telemóvel"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"A zona Wi-Fi ou a ligação (à Internet) via telemóvel está ativada"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Podem aplicar-se custos adicionais em roaming."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-pt/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pt/strings.xml new file mode 100644 index 000000000000..d8866170c191 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-pt/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"O tethering não tem Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível conectar os dispositivos"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar o tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ponto de acesso ou tethering ativado"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pode haver cobranças extras durante o roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ro/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ro/strings.xml new file mode 100644 index 000000000000..8d87a9e516ad --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ro/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Procesul de tethering nu are internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Dispozitivele nu se pot conecta"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Dezactivați procesul de tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"S-a activat hotspotul sau tethering"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Se pot aplica taxe suplimentare pentru roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ru/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ru/strings.xml new file mode 100644 index 000000000000..dbdb9ebe4931 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ru/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Режим модема используется без доступа к Интернету"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Невозможно подключить устройства."</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Отключить режим модема"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Включены точка доступа или режим модема"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"За использование услуг связи в роуминге может взиматься дополнительная плата."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-si/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-si/strings.xml new file mode 100644 index 000000000000..d8301e41c2b2 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-si/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ටෙදරින් හට අන්තර්ජාලය නැත"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"උපාංගවලට සම්බන්ධ විය නොහැකිය"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ටෙදරින් ක්රියාවිරහිත කරන්න"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"හොට්ස්පොට් හෝ ටෙදරින් ක්රියාත්මකයි"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"රෝමිං අතරතුර අමතර ගාස්තු අදාළ විය හැකිය"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-sk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sk/strings.xml new file mode 100644 index 000000000000..bef71363f450 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-sk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nemá internetové pripojenie"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Zariadenia sa nemôžu pripojiť"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vypnúť tethering"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Je zapnutý hotspot alebo tethering"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Počas roamingu vám môžu byť účtované ďalšie poplatky"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-sl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sl/strings.xml new file mode 100644 index 000000000000..3202c62e8a3a --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-sl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Internetna povezava prek mobilnega telefona ni vzpostavljena"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Napravi se ne moreta povezati"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Izklopi internetno povezavo prek mobilnega telefona"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Dostopna točka ali internetna povezava prek mobilnega telefona je vklopljena"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Med gostovanjem lahko nastanejo dodatni stroški"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-sq/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sq/strings.xml new file mode 100644 index 000000000000..37f6ad286880 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-sq/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ndarja e internetit nuk ka internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Pajisjet nuk mund të lidhen"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Çaktivizo ndarjen e internetit"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Zona e qasjes për internet ose ndarja e internetit është aktive"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Mund të zbatohen tarifime shtesë kur je në roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-sr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sr/strings.xml new file mode 100644 index 000000000000..5566d03ed13a --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-sr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Привезивање нема приступ интернету"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Повезивање уређаја није успело"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Искључи привезивање"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Укључен је хотспот или привезивање"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Можда важе додатни трошкови у ромингу"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-sv/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sv/strings.xml new file mode 100644 index 000000000000..9765acd0cf46 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-sv/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Det finns ingen internetanslutning för internetdelningen"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enheterna kan inte anslutas"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Inaktivera internetdelning"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Surfzon eller internetdelning har aktiverats"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ytterligare avgifter kan tillkomma vid roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-sw/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sw/strings.xml new file mode 100644 index 000000000000..cf850c9cd222 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-sw/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Kipengele cha kusambaza mtandao hakina intaneti"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Imeshindwa kuunganisha vifaa"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Zima kipengele cha kusambaza mtandao"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Umewasha kipengele cha kusambaza mtandao au mtandao pepe"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Huenda ukatozwa gharama za ziada ukitumia mitandao ya ng\'ambo"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml new file mode 100644 index 000000000000..ea04821e33bd --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- no translation found for no_upstream_notification_title (5030042590486713460) --> + <skip /> + <!-- no translation found for no_upstream_notification_message (3843613362272973447) --> + <skip /> + <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) --> + <skip /> + <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) --> + <skip /> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-te/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-te/strings.xml new file mode 100644 index 000000000000..937d34d52027 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-te/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"టెథరింగ్ చేయడానికి ఇంటర్నెట్ కనెక్షన్ లేదు"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"పరికరాలు కనెక్ట్ అవ్వడం లేదు"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"టెథరింగ్ను ఆఫ్ చేయండి"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"హాట్స్పాట్ లేదా టెథరింగ్ ఆన్లో ఉంది"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"రోమింగ్లో ఉన్నప్పుడు అదనపు ఛార్జీలు వర్తించవచ్చు"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-th/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-th/strings.xml new file mode 100644 index 000000000000..f781fae5252e --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-th/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือไม่มีอินเทอร์เน็ต"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"อุปกรณ์เชื่อมต่อไม่ได้"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ปิดการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ฮอตสปอตหรือการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือเปิดอยู่"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"อาจมีค่าใช้จ่ายเพิ่มเติมขณะโรมมิ่ง"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-tl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-tl/strings.xml new file mode 100644 index 000000000000..8d5d46537334 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-tl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Walang internet ang pag-tether"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Hindi makakonekta ang mga device"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"I-off ang pag-tether"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Naka-on ang Hotspot o pag-tether"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Posibleng magkaroon ng mga karagdagang singil habang nagro-roam"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-tr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-tr/strings.xml new file mode 100644 index 000000000000..80cab33ac05e --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-tr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering\'in internet bağlantısı yok"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Cihazlar bağlanamıyor"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering\'i kapat"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot veya tethering açık"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Dolaşım sırasında ek ücretler uygulanabilir"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-uk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-uk/strings.xml new file mode 100644 index 000000000000..c05932a5ae7f --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-uk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Телефон, який використовується як модем, не підключений до Інтернету"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Не вдається підключити пристрої"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Вимкнути використання телефона як модема"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Увімкнено точку доступу або використання телефона як модема"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"У роумінгу може стягуватися додаткова плата"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-ur/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ur/strings.xml new file mode 100644 index 000000000000..d820eee8ba3c --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-ur/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"ٹیدرنگ میں انٹرنیٹ نہیں ہے"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"آلات منسلک نہیں ہو سکتے"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ٹیدرنگ آف کریں"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ہاٹ اسپاٹ یا ٹیدرنگ آن ہے"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"رومنگ کے دوران اضافی چارجز لاگو ہو سکتے ہیں"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-uz/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-uz/strings.xml new file mode 100644 index 000000000000..726148aaee5a --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-uz/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modem internetga ulanmagan"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Qurilmalar ulanmadi"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Modem rejimini faolsizlantirish"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot yoki modem rejimi yoniq"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rouming vaqtida qoʻshimcha haq olinishi mumkin"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-vi/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-vi/strings.xml new file mode 100644 index 000000000000..b7cb0456b673 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-vi/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Không có Internet để chia sẻ kết Internet"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Các thiết bị không thể kết nối"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tắt tính năng chia sẻ Internet"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Điểm phát sóng hoặc tính năng chia sẻ Internet đang bật"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Bạn có thể mất thêm phí dữ liệu khi chuyển vùng"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml new file mode 100644 index 000000000000..af91afff9a4c --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"共享网络未连接到互联网"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"设备无法连接"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"关闭网络共享"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"热点或网络共享已开启"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"漫游时可能会产生额外的费用"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml new file mode 100644 index 000000000000..28e6b80c01a9 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過網絡共享連線至互聯網"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"裝置無法連接"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉網絡共享"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"熱點或網絡共享已開啟"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"漫遊時可能需要支付額外費用"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml new file mode 100644 index 000000000000..05b90692ea7b --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過數據連線連上網際網路"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"裝置無法連線"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉數據連線"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"無線基地台或數據連線已開啟"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"使用漫遊服務可能須支付額外費用"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004-zu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zu/strings.xml new file mode 100644 index 000000000000..11eb66621971 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004-zu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ukusebenzisa ifoni njengemodemu akunayo i-inthanethi"</string> + <string name="no_upstream_notification_message" msgid="3843613362272973447">"Amadivayisi awakwazi ukuxhumeka"</string> + <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vala ukusebenzisa ifoni njengemodemu"</string> + <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"I-hotspot noma ukusebenzisa ifoni njengemodemu kuvuliwe"</string> + <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Kungaba nezinkokhelo ezengeziwe uma uzula"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004/strings.xml b/packages/Tethering/res/values-mcc310-mnc004/strings.xml index 9dadd49cf8a4..ce9ff6080717 100644 --- a/packages/Tethering/res/values-mcc310-mnc004/strings.xml +++ b/packages/Tethering/res/values-mcc310-mnc004/strings.xml @@ -25,6 +25,4 @@ <string name="upstream_roaming_notification_title">Hotspot or tethering is on</string> <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string> - <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> - <string name="upstream_roaming_notification_continue_button">Continue</string> </resources> diff --git a/packages/Tethering/res/values-mcc310-mnc120/strings.xml b/packages/Tethering/res/values-mcc310-mnc120/strings.xml deleted file mode 100644 index 618df90c7105..000000000000 --- a/packages/Tethering/res/values-mcc310-mnc120/strings.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2020 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- String for tethered notification title with client number info. --> - <plurals name="tethered_notification_title_with_client_number"> - <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item> - <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item> - </plurals> -</resources>
\ No newline at end of file diff --git a/packages/Tethering/res/values-mcc311-mnc480-af/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-af/strings.xml new file mode 100644 index 000000000000..9bfa5317a9e4 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-af/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Verbinding het nie internet nie"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Toestelle kan nie koppel nie"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Skakel verbinding af"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Warmkol of verbinding is aan"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Bykomende heffings kan geld terwyl jy swerf"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-am/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-am/strings.xml new file mode 100644 index 000000000000..5949dfa776d7 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-am/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ማስተሳሰር ምንም በይነመረብ የለውም"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"መሣሪያዎችን ማገናኘት አይቻልም"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ማስተሳሰርን አጥፋ"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"መገናኛ ነጥብ ወይም ማስተሳሰር በርቷል"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"በሚያንዣብብበት ጊዜ ተጨማሪ ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ar/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ar/strings.xml new file mode 100644 index 000000000000..8467f9b1f5cf --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ar/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ما مِن اتصال بالإنترنت خلال التوصيل"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"تعذّر اتصال الأجهزة"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"إيقاف التوصيل"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"نقطة الاتصال أو التوصيل مفعّلان"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"قد يتم تطبيق رسوم إضافية أثناء التجوال."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-as/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-as/strings.xml new file mode 100644 index 000000000000..9776bd89da48 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-as/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"টে\'ডাৰিঙৰ ইণ্টাৰনেট নাই"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"ডিভাইচসমূহ সংযোগ কৰিব নোৱাৰি"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"টে\'ডাৰিং অফ কৰক"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"হটস্পট অথবা টে\'ডাৰিং অন আছে"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ৰ\'মিঙত থাকিলে অতিৰিক্ত মাচুল প্ৰযোজ্য হ’ব পাৰে"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-az/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-az/strings.xml new file mode 100644 index 000000000000..e6d3eaf9f07c --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-az/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Modemin internetə girişi yoxdur"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Cihazları qoşmaq mümkün deyil"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Modemi deaktiv edin"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot və ya modem aktivdir"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rouminq zamanı əlavə ödənişlər tətbiq edilə bilər"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml new file mode 100644 index 000000000000..4c8a1df8eece --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Privezivanje nema pristup internetu"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Povezivanje uređaja nije uspelo"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključi privezivanje"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Uključen je hotspot ili privezivanje"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Možda važe dodatni troškovi u romingu"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-be/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-be/strings.xml new file mode 100644 index 000000000000..edfa41e1ffd3 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-be/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Рэжым мадэма выкарыстоўваецца без доступу да інтэрнэту"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Не ўдалося падключыць прылады"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Выключыць рэжым мадэма"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Хот-спот або рэжым мадэма ўключаны"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Пры выкарыстанні роўмінгу можа спаганяцца дадатковая плата"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-bg/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-bg/strings.xml new file mode 100644 index 000000000000..f56398196f51 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-bg/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Тетърингът няма връзка с интернет"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Устройствата не могат да установят връзка"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Изключване на тетъринга"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Точката за достъп или тетърингът са включени"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Възможно е да ви бъдат начислени допълнителни такси при роуминг"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-bn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-bn/strings.xml new file mode 100644 index 000000000000..d8ecd2e988f9 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-bn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"টিথারিং করার জন্য কোনও ইন্টারনেট কানেকশন নেই"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"ডিভাইস কানেক্ট করতে পারছে না"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"টিথারিং বন্ধ করুন"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"হটস্পট বা টিথারিং চালু আছে"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"রোমিংয়ের সময় অতিরিক্ত চার্জ করা হতে পারে"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-bs/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-bs/strings.xml new file mode 100644 index 000000000000..b85fd5e28577 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-bs/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Povezivanje putem mobitela nema internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Uređaji se ne mogu povezati"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključi povezivanje putem mobitela"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Pristupna tačka ili povezivanje putem mobitela je uključeno"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Mogu nastati dodatni troškovi u romingu"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ca/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ca/strings.xml new file mode 100644 index 000000000000..a3572151be6b --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ca/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"La compartició de xarxa no té accés a Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"No es poden connectar els dispositius"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactiva la compartició de xarxa"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"S\'ha activat el punt d\'accés Wi‑Fi o la compartició de xarxa"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"És possible que s\'apliquin costos addicionals en itinerància"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-cs/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-cs/strings.xml new file mode 100644 index 000000000000..91196be9e557 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-cs/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nemá připojení k internetu"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Zařízení se nemůžou připojit"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vypnout tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Je zapnutý hotspot nebo tethering"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Při roamingu mohou být účtovány dodatečné poplatky"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-da/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-da/strings.xml new file mode 100644 index 000000000000..196890011d50 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-da/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Netdeling har ingen internetforbindelse"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enheder kan ikke oprette forbindelse"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Deaktiver netdeling"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot eller netdeling er aktiveret"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Der opkræves muligvis yderligere gebyrer ved roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-de/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-de/strings.xml new file mode 100644 index 000000000000..eb3f8c52c0c5 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-de/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering hat keinen Internetzugriff"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Geräte können sich nicht verbinden"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering deaktivieren"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot oder Tethering ist aktiviert"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Für das Roaming können zusätzliche Gebühren anfallen"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-el/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-el/strings.xml new file mode 100644 index 000000000000..56c3d81b634e --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-el/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Η σύνδεση δεν έχει πρόσβαση στο διαδίκτυο"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Δεν είναι δυνατή η σύνδεση των συσκευών"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Απενεργοποιήστε τη σύνδεση"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ενεργό σημείο πρόσβασης Wi-Fi ή ενεργή σύνδεση"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ενδέχεται να ισχύουν επιπλέον χρεώσεις κατά την περιαγωγή."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml new file mode 100644 index 000000000000..dd1a1971cdd8 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml new file mode 100644 index 000000000000..dd1a1971cdd8 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml new file mode 100644 index 000000000000..dd1a1971cdd8 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml new file mode 100644 index 000000000000..dd1a1971cdd8 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml new file mode 100644 index 000000000000..d3347aae207d --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml new file mode 100644 index 000000000000..2f0504f07de7 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"La conexión mediante dispositivo móvil no tiene Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"No se pueden conectar los dispositivos"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión mediante dispositivo móvil"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Se activó el hotspot o la conexión mediante dispositivo móvil"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Es posible que se apliquen cargos adicionales por roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-es/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-es/strings.xml new file mode 100644 index 000000000000..2d8f88242502 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-es/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"La conexión no se puede compartir, porque no hay acceso a Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Los dispositivos no se pueden conectar"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión compartida"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Punto de acceso o conexión compartida activados"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Puede que se apliquen cargos adicionales en itinerancia"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-et/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-et/strings.xml new file mode 100644 index 000000000000..8493c470710d --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-et/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Jagamisel puudub internetiühendus"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Seadmed ei saa ühendust luua"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Lülita jagamine välja"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Kuumkoht või jagamine on sisse lülitatud"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rändluse kasutamisega võivad kaasneda lisatasud"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-eu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-eu/strings.xml new file mode 100644 index 000000000000..33bccab3e88c --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-eu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Konexioa partekatzeko aukerak ez du Interneteko konexiorik"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Ezin dira konektatu gailuak"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desaktibatu konexioa partekatzeko aukera"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Wifi-gunea edo konexioa partekatzeko aukera aktibatuta dago"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Baliteke kostu gehigarriak ordaindu behar izatea ibiltaritzan"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-fa/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fa/strings.xml new file mode 100644 index 000000000000..cf8a0cc27705 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-fa/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"«اشتراکگذاری اینترنت» به اینترنت دسترسی ندارد"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"دستگاهها متصل نمیشوند"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"خاموش کردن «اشتراکگذاری اینترنت»"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"«نقطه اتصال» یا «اشتراکگذاری اینترنت» روشن است"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ممکن است درحین فراگردی تغییرات دیگر اعمال شود"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-fi/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fi/strings.xml new file mode 100644 index 000000000000..6a3ab806db98 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-fi/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Ei jaettavaa internetyhteyttä"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Laitteet eivät voi muodostaa yhteyttä"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Laita yhteyden jakaminen pois päältä"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot tai yhteyden jakaminen on päällä"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Roaming voi aiheuttaa lisämaksuja"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml new file mode 100644 index 000000000000..ffb9bf60472e --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Le partage de connexion n\'est pas connecté à Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossible de connecter les appareils"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Désactiver le partage de connexion"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Le point d\'accès ou le partage de connexion est activé"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-fr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fr/strings.xml new file mode 100644 index 000000000000..768bce3f0ab1 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-fr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Aucune connexion à Internet n\'est disponible pour le partage de connexion"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossible de connecter les appareils"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Désactiver le partage de connexion"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Le point d\'accès ou le partage de connexion est activé"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-gl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-gl/strings.xml new file mode 100644 index 000000000000..0c4195a7caf3 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-gl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"A conexión compartida non ten Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Non se puideron conectar os dispositivos"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión compartida"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Está activada a zona wifi ou a conexión compartida"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pódense aplicar cargos adicionais en itinerancia"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-gu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-gu/strings.xml new file mode 100644 index 000000000000..e9d33a7db259 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-gu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ઇન્ટરનેટ શેર કરવાની સુવિધામાં ઇન્ટરનેટ નથી"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"ડિવાઇસ કનેક્ટ કરી શકાતા નથી"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરો"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"હૉટસ્પૉટ અથવા ઇન્ટરનેટ શેર કરવાની સુવિધા ચાલુ છે"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"રોમિંગમાં વધારાના શુલ્ક લાગી શકે છે"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-hi/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hi/strings.xml new file mode 100644 index 000000000000..aa418ac5d3bb --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-hi/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिंग से इंटरनेट नहीं चल रहा"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"डिवाइस कनेक्ट नहीं हो पा रहे"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिंग बंद करें"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हॉटस्पॉट या टेदरिंग चालू है"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिंग के दौरान अतिरिक्त शुल्क लग सकता है"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-hr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hr/strings.xml new file mode 100644 index 000000000000..51c524afbc53 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-hr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Modemsko povezivanje nema internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Uređaji se ne mogu povezati"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključivanje modemskog povezivanja"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Uključena je žarišna točka ili modemsko povezivanje"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"U roamingu su mogući dodatni troškovi"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-hu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hu/strings.xml new file mode 100644 index 000000000000..164e45edd142 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-hu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Nincs internetkapcsolat az internet megosztásához"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Az eszközök nem tudnak csatlakozni"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Internetmegosztás kikapcsolása"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"A hotspot vagy az internetmegosztás be van kapcsolva"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Roaming során további díjak léphetnek fel"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-hy/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hy/strings.xml new file mode 100644 index 000000000000..e76c0a4c80d5 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-hy/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Մոդեմի ռեժիմի կապը բացակայում է"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Չհաջողվեց միացնել սարքը"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Անջատել մոդեմի ռեժիմը"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Թեժ կետը կամ մոդեմի ռեժիմը միացված է"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ռոումինգում կարող են լրացուցիչ վճարներ գանձվել"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-in/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-in/strings.xml new file mode 100644 index 000000000000..2b817f8abd17 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-in/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tidak ada koneksi internet di tethering"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Perangkat tidak dapat terhubung"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Nonaktifkan tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot atau tethering aktif"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Biaya tambahan mungkin berlaku saat roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-is/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-is/strings.xml new file mode 100644 index 000000000000..a338d9c7cab8 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-is/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tjóðrun er ekki með internettengingu"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Tæki geta ekki tengst"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Slökkva á tjóðrun"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Kveikt er á heitum reit eða tjóðrun"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Viðbótargjöld kunna að eiga við í reiki"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-it/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-it/strings.xml new file mode 100644 index 000000000000..77769c2ac56c --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-it/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Nessuna connessione a Internet per il tethering"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossibile connettere i dispositivi"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Disattiva il tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot o tethering attivi"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Potrebbero essere applicati costi aggiuntivi durante il roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-iw/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-iw/strings.xml new file mode 100644 index 000000000000..5267b5126435 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-iw/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"אי אפשר להפעיל את תכונת שיתוף האינטרנט בין מכשירים כי אין חיבור לאינטרנט"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"למכשירים אין אפשרות להתחבר"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"השבתה של שיתוף האינטרנט בין מכשירים"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"תכונת הנקודה לשיתוף אינטרנט או תכונת שיתוף האינטרנט בין מכשירים פועלת"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ייתכנו חיובים נוספים בעת נדידה"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ja/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ja/strings.xml new file mode 100644 index 000000000000..66a9a6dd35c2 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ja/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"テザリングがインターネットに接続されていません"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"デバイスを接続できません"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"テザリングを OFF にする"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"アクセス ポイントまたはテザリングが ON です"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ローミング時に追加料金が発生することがあります"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ka/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ka/strings.xml new file mode 100644 index 000000000000..d8ad8808498f --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ka/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ტეტერინგს არ აქვს ინტერნეტზე წვდომა"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"მოწყობილობები ვერ ახერხებენ დაკავშირებას"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ტეტერინგის გამორთვა"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ჩართულია უსადენო ქსელი ან ტეტერინგი"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"როუმინგის გამოყენებისას შეიძლება ჩამოგეჭრათ დამატებითი საფასური"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-kk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-kk/strings.xml new file mode 100644 index 000000000000..1ddd6b419b57 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-kk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Тетеринг режимі интернет байланысынсыз пайдаланылуда"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Құрылғыларды байланыстыру мүмкін емес"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Тетерингіні өшіру"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Хотспот немесе тетеринг қосулы"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роуминг кезінде қосымша ақы алынуы мүмкін."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-km/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-km/strings.xml new file mode 100644 index 000000000000..cf5a1379ccc7 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-km/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ការភ្ជាប់មិនមានអ៊ីនធឺណិតទេ"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"មិនអាចភ្ជាប់ឧបករណ៍បានទេ"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"បិទការភ្ជាប់"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ហតស្ប៉ត ឬការភ្ជាប់ត្រូវបានបើក"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"អាចមានការគិតថ្លៃបន្ថែម នៅពេលរ៉ូមីង"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-kn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-kn/strings.xml new file mode 100644 index 000000000000..68ae68bc1998 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-kn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ಟೆಥರಿಂಗ್ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಕನೆಕ್ಷನ್ ಹೊಂದಿಲ್ಲ"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"ಸಾಧನಗಳನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ಟೆಥರಿಂಗ್ ಆಫ್ ಮಾಡಿ"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ಹಾಟ್ಸ್ಪಾಟ್ ಅಥವಾ ಟೆಥರಿಂಗ್ ಆನ್ ಆಗಿದೆ"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ರೋಮಿಂಗ್ನಲ್ಲಿರುವಾಗ ಹೆಚ್ಚುವರಿ ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ko/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ko/strings.xml new file mode 100644 index 000000000000..17185ba2d063 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ko/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"테더링으로 인터넷을 사용할 수 없음"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"기기에서 연결할 수 없음"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"테더링 사용 중지"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"핫스팟 또는 테더링 켜짐"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"로밍 중에는 추가 요금이 발생할 수 있습니다."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ky/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ky/strings.xml new file mode 100644 index 000000000000..6a9fb9810cc6 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ky/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Модем режими Интернети жок колдонулууда"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Түзмөктөр туташпай жатат"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Модем режимин өчүрүү"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Байланыш түйүнү же модем режими күйүк"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роумингде кошумча акы алынышы мүмкүн"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-lo/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-lo/strings.xml new file mode 100644 index 000000000000..bcc4b5762678 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-lo/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ການປ່ອຍສັນຍານບໍ່ມີອິນເຕີເນັດ"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"ອຸປະກອນບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ປິດການປ່ອຍສັນຍານ"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ເປີດໃຊ້ຮັອດສະປອດ ຫຼື ການປ່ອຍສັນຍານຢູ່"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ອາດມີຄ່າໃຊ້ຈ່າຍເພີ່ມເຕີມໃນລະຫວ່າງການໂຣມມິງ"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-lt/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-lt/strings.xml new file mode 100644 index 000000000000..011c2c11fb88 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-lt/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Nėra įrenginio kaip modemo naudojimo interneto ryšio"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Nepavyko susieti įrenginių"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Išjungti įrenginio kaip modemo naudojimą"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Įjungtas viešosios interneto prieigos taškas arba įrenginio kaip modemo naudojimas"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Veikiant tarptinkliniam ryšiui gali būti taikomi papildomi mokesčiai"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-lv/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-lv/strings.xml new file mode 100644 index 000000000000..5cb2f3b7aac8 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-lv/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Piesaistei nav interneta savienojuma"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Nevar savienot ierīces"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Izslēgt piesaisti"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ir ieslēgts tīklājs vai piesaiste"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Viesabonēšanas laikā var tikt piemērota papildu samaksa"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-mk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-mk/strings.xml new file mode 100644 index 000000000000..4cbfd887c57e --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-mk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Нема интернет преку мобилен"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Уредите не може да се поврзат"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Исклучи интернет преку мобилен"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Точката на пристап или интернетот преку мобилен е вклучен"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"При роаминг може да се наплатат дополнителни трошоци"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ml/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ml/strings.xml new file mode 100644 index 000000000000..9cf4eaf34a97 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ml/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ടെതറിംഗിന് ഇന്റർനെറ്റ് ഇല്ല"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"ഉപകരണങ്ങൾ കണക്റ്റ് ചെയ്യാനാവില്ല"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ടെതറിംഗ് ഓഫാക്കുക"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ഹോട്ട്സ്പോട്ട് അല്ലെങ്കിൽ ടെതറിംഗ് ഓണാണ്"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"റോമിംഗ് ചെയ്യുമ്പോൾ അധിക നിരക്കുകൾ ബാധകമായേക്കാം"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-mn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-mn/strings.xml new file mode 100644 index 000000000000..47c82c14d9d6 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-mn/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Модемд интернэт алга байна"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Төхөөрөмжүүд холбогдох боломжгүй байна"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Модем болгохыг унтраах"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Сүлжээний цэг эсвэл модем болгох асаалттай байна"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роумингийн үеэр нэмэлт төлбөр нэхэмжилж болзошгүй"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-mr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-mr/strings.xml new file mode 100644 index 000000000000..ad9e809ab27d --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-mr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिंगला इंटरनेट नाही"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"डिव्हाइस कनेक्ट होऊ शकत नाहीत"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिंग बंद करा"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हॉटस्पॉट किंवा टेदरिंग सुरू आहे"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिंगदरम्यान अतिरिक्त शुल्क लागू होऊ शकतात"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ms/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ms/strings.xml new file mode 100644 index 000000000000..e708cb8717b3 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ms/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Penambatan tiada Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Peranti tidak dapat disambungkan"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Matikan penambatan"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Tempat liputan atau penambatan dihidupkan"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Caj tambahan mungkin digunakan semasa perayauan"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-my/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-my/strings.xml new file mode 100644 index 000000000000..ba5462250b05 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-my/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းတွင် အင်တာနက် မရှိပါ"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"စက်များ ချိတ်ဆက်၍ မရပါ"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ပိတ်ရန်"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ဟော့စပေါ့ (သို့) မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ဖွင့်ထားသည်"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ပြင်ပကွန်ရက်နှင့် ချိတ်ဆက်သည့်အခါ နောက်ထပ်ကျသင့်မှုများ ရှိနိုင်သည်"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-nb/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-nb/strings.xml new file mode 100644 index 000000000000..57db484a2543 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-nb/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Internettdeling har ikke internettilgang"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enhetene kan ikke koble til"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Slå av internettdeling"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Wi-Fi-sone eller internettdeling er på"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ytterligere kostnader kan påløpe under roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml new file mode 100644 index 000000000000..617c50dd0ce8 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- no translation found for no_upstream_notification_title (611650570559011140) --> + <skip /> + <!-- no translation found for no_upstream_notification_message (6508394877641864863) --> + <skip /> + <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) --> + <skip /> + <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) --> + <skip /> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-nl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-nl/strings.xml new file mode 100644 index 000000000000..b08133f4e592 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-nl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering heeft geen internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Apparaten kunnen niet worden verbonden"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering uitschakelen"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot of tethering is ingeschakeld"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Er kunnen extra kosten voor roaming in rekening worden gebracht."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-or/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-or/strings.xml new file mode 100644 index 000000000000..1ad4ca354ad5 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-or/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ଟିଥରିଂ ପାଇଁ କୌଣସି ଇଣ୍ଟର୍ନେଟ୍ ସଂଯୋଗ ନାହିଁ"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"ଡିଭାଇସଗୁଡ଼ିକ ସଂଯୋଗ କରାଯାଇପାରିବ ନାହିଁ"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ଟିଥରିଂ ବନ୍ଦ କରନ୍ତୁ"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ହଟସ୍ପଟ୍ କିମ୍ବା ଟିଥରିଂ ଚାଲୁ ଅଛି"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ରୋମିଂରେ ଥିବା ସମୟରେ ଅତିରିକ୍ତ ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-pa/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pa/strings.xml new file mode 100644 index 000000000000..88def563d85a --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-pa/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ਟੈਦਰਿੰਗ ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"ਡੀਵਾਈਸ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ਟੈਦਰਿੰਗ ਬੰਦ ਕਰੋ"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ਹੌਟਸਪੌਟ ਜਾਂ ਟੈਦਰਿੰਗ ਚਾਲੂ ਹੈ"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ਰੋਮਿੰਗ ਦੌਰਾਨ ਵਧੀਕ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-pl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pl/strings.xml new file mode 100644 index 000000000000..f9890abdc26b --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-pl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nie ma internetu"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Urządzenia nie mogą się połączyć"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Wyłącz tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot lub tethering jest włączony"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Podczas korzystania z roamingu mogą zostać naliczone dodatkowe opłaty"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml new file mode 100644 index 000000000000..ce3b88479f09 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"O tethering não tem Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível conectar os dispositivos"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar o tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ponto de acesso ou tethering ativado"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pode haver cobranças extras durante o roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml new file mode 100644 index 000000000000..7e883ea57682 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"A ligação (à Internet) via telemóvel não tem Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível ligar os dispositivos"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar ligação (à Internet) via telemóvel"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"A zona Wi-Fi ou a ligação (à Internet) via telemóvel está ativada"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Podem aplicar-se custos adicionais em roaming."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-pt/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pt/strings.xml new file mode 100644 index 000000000000..ce3b88479f09 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-pt/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"O tethering não tem Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível conectar os dispositivos"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar o tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ponto de acesso ou tethering ativado"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pode haver cobranças extras durante o roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ro/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ro/strings.xml new file mode 100644 index 000000000000..1009417316ed --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ro/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Procesul de tethering nu are internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Dispozitivele nu se pot conecta"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Dezactivați procesul de tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"S-a activat hotspotul sau tethering"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Se pot aplica taxe suplimentare pentru roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ru/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ru/strings.xml new file mode 100644 index 000000000000..88683bed95b8 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ru/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Режим модема используется без доступа к Интернету"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Невозможно подключить устройства."</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Отключить режим модема"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Включены точка доступа или режим модема"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"За использование услуг связи в роуминге может взиматься дополнительная плата."</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-si/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-si/strings.xml new file mode 100644 index 000000000000..176bcdb797c6 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-si/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ටෙදරින් හට අන්තර්ජාලය නැත"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"උපාංගවලට සම්බන්ධ විය නොහැකිය"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ටෙදරින් ක්රියාවිරහිත කරන්න"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"හොට්ස්පොට් හෝ ටෙදරින් ක්රියාත්මකයි"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"රෝමිං අතරතුර අමතර ගාස්තු අදාළ විය හැකිය"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-sk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sk/strings.xml new file mode 100644 index 000000000000..b9e2127fa879 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-sk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nemá internetové pripojenie"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Zariadenia sa nemôžu pripojiť"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vypnúť tethering"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Je zapnutý hotspot alebo tethering"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Počas roamingu vám môžu byť účtované ďalšie poplatky"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-sl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sl/strings.xml new file mode 100644 index 000000000000..e8140e686a0c --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-sl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Internetna povezava prek mobilnega telefona ni vzpostavljena"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Napravi se ne moreta povezati"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Izklopi internetno povezavo prek mobilnega telefona"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Dostopna točka ali internetna povezava prek mobilnega telefona je vklopljena"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Med gostovanjem lahko nastanejo dodatni stroški"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-sq/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sq/strings.xml new file mode 100644 index 000000000000..61e698d6e8ab --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-sq/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Ndarja e internetit nuk ka internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Pajisjet nuk mund të lidhen"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Çaktivizo ndarjen e internetit"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Zona e qasjes për internet ose ndarja e internetit është aktive"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Mund të zbatohen tarifime shtesë kur je në roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-sr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sr/strings.xml new file mode 100644 index 000000000000..b4c411c35475 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-sr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Привезивање нема приступ интернету"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Повезивање уређаја није успело"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Искључи привезивање"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Укључен је хотспот или привезивање"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Можда важе додатни трошкови у ромингу"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-sv/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sv/strings.xml new file mode 100644 index 000000000000..4f543e47b998 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-sv/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Det finns ingen internetanslutning för internetdelningen"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enheterna kan inte anslutas"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Inaktivera internetdelning"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Surfzon eller internetdelning har aktiverats"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ytterligare avgifter kan tillkomma vid roaming"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-sw/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sw/strings.xml new file mode 100644 index 000000000000..ac347ab485e0 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-sw/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Kipengele cha kusambaza mtandao hakina intaneti"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Imeshindwa kuunganisha vifaa"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Zima kipengele cha kusambaza mtandao"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Umewasha kipengele cha kusambaza mtandao au mtandao pepe"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Huenda ukatozwa gharama za ziada ukitumia mitandao ya ng\'ambo"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml new file mode 100644 index 000000000000..0e437593ee87 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- no translation found for no_upstream_notification_title (611650570559011140) --> + <skip /> + <!-- no translation found for no_upstream_notification_message (6508394877641864863) --> + <skip /> + <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) --> + <skip /> + <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) --> + <skip /> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-te/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-te/strings.xml new file mode 100644 index 000000000000..9360297dd807 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-te/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"టెథరింగ్ చేయడానికి ఇంటర్నెట్ కనెక్షన్ లేదు"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"పరికరాలు కనెక్ట్ అవ్వడం లేదు"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"టెథరింగ్ను ఆఫ్ చేయండి"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"హాట్స్పాట్ లేదా టెథరింగ్ ఆన్లో ఉంది"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"రోమింగ్లో ఉన్నప్పుడు అదనపు ఛార్జీలు వర్తించవచ్చు"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-th/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-th/strings.xml new file mode 100644 index 000000000000..9c4d7e08f2b6 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-th/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือไม่มีอินเทอร์เน็ต"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"อุปกรณ์เชื่อมต่อไม่ได้"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ปิดการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ฮอตสปอตหรือการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือเปิดอยู่"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"อาจมีค่าใช้จ่ายเพิ่มเติมขณะโรมมิ่ง"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-tl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-tl/strings.xml new file mode 100644 index 000000000000..a7c78a593267 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-tl/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Walang internet ang pag-tether"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Hindi makakonekta ang mga device"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"I-off ang pag-tether"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Naka-on ang Hotspot o pag-tether"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Posibleng magkaroon ng mga karagdagang singil habang nagro-roam"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-tr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-tr/strings.xml new file mode 100644 index 000000000000..93da2c3f7981 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-tr/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering\'in internet bağlantısı yok"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Cihazlar bağlanamıyor"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering\'i kapat"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot veya tethering açık"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Dolaşım sırasında ek ücretler uygulanabilir"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-uk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-uk/strings.xml new file mode 100644 index 000000000000..ee0dcd2c4b6a --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-uk/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Телефон, який використовується як модем, не підключений до Інтернету"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Не вдається підключити пристрої"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Вимкнути використання телефона як модема"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Увімкнено точку доступу або використання телефона як модема"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"У роумінгу може стягуватися додаткова плата"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-ur/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ur/strings.xml new file mode 100644 index 000000000000..41cd28eef9bd --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-ur/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"ٹیدرنگ میں انٹرنیٹ نہیں ہے"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"آلات منسلک نہیں ہو سکتے"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ٹیدرنگ آف کریں"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ہاٹ اسپاٹ یا ٹیدرنگ آن ہے"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"رومنگ کے دوران اضافی چارجز لاگو ہو سکتے ہیں"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-uz/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-uz/strings.xml new file mode 100644 index 000000000000..c847bc943bd4 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-uz/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Modem internetga ulanmagan"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Qurilmalar ulanmadi"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Modem rejimini faolsizlantirish"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot yoki modem rejimi yoniq"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rouming vaqtida qoʻshimcha haq olinishi mumkin"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-vi/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-vi/strings.xml new file mode 100644 index 000000000000..a74326f09ec5 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-vi/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Không có Internet để chia sẻ kết Internet"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Các thiết bị không thể kết nối"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tắt tính năng chia sẻ Internet"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Điểm phát sóng hoặc tính năng chia sẻ Internet đang bật"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Bạn có thể mất thêm phí dữ liệu khi chuyển vùng"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml new file mode 100644 index 000000000000..d7370036e351 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"共享网络未连接到互联网"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"设备无法连接"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"关闭网络共享"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"热点或网络共享已开启"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"漫游时可能会产生额外的费用"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml new file mode 100644 index 000000000000..f378a9dc2cfb --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過網絡共享連線至互聯網"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"裝置無法連接"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉網絡共享"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"熱點或網絡共享已開啟"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"漫遊時可能需要支付額外費用"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml new file mode 100644 index 000000000000..ea01b943fbe8 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過數據連線連上網際網路"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"裝置無法連線"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉數據連線"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"無線基地台或數據連線已開啟"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"使用漫遊服務可能須支付額外費用"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480-zu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zu/strings.xml new file mode 100644 index 000000000000..32f6df56f154 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480-zu/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="no_upstream_notification_title" msgid="611650570559011140">"Ukusebenzisa ifoni njengemodemu akunayo i-inthanethi"</string> + <string name="no_upstream_notification_message" msgid="6508394877641864863">"Amadivayisi awakwazi ukuxhumeka"</string> + <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vala ukusebenzisa ifoni njengemodemu"</string> + <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"I-hotspot noma ukusebenzisa ifoni njengemodemu kuvuliwe"</string> + <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Kungaba nezinkokhelo ezengeziwe uma uzula"</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480/strings.xml b/packages/Tethering/res/values-mcc311-mnc480/strings.xml index 9dadd49cf8a4..ce9ff6080717 100644 --- a/packages/Tethering/res/values-mcc311-mnc480/strings.xml +++ b/packages/Tethering/res/values-mcc311-mnc480/strings.xml @@ -25,6 +25,4 @@ <string name="upstream_roaming_notification_title">Hotspot or tethering is on</string> <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string> - <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> - <string name="upstream_roaming_notification_continue_button">Continue</string> </resources> diff --git a/packages/Tethering/res/values-mk/strings.xml b/packages/Tethering/res/values-mk/strings.xml index 0fab8aa4761f..9ad9b9a58935 100644 --- a/packages/Tethering/res/values-mk/strings.xml +++ b/packages/Tethering/res/values-mk/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Поврзувањето или точката на пристап се активни"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Допрете за поставување."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Врзувањето е оневозможено"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Контактирајте со администраторот за детали"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Активно е врзување или точка на пристап"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Допрете за поставување."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Врзувањето е оневозможено"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Контактирајте со администраторот за детали"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус на точката на пристап и врзувањето"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ml/strings.xml b/packages/Tethering/res/values-ml/strings.xml index fd7e556e3899..9db79ce220a4 100644 --- a/packages/Tethering/res/values-ml/strings.xml +++ b/packages/Tethering/res/values-ml/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ടെതറിംഗ് അല്ലെങ്കിൽ ഹോട്ട്സ്പോട്ട് സജീവമാണ്"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"സജ്ജമാക്കാൻ ടാപ്പുചെയ്യുക."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ടെതറിംഗ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"വിശദവിവരങ്ങൾക്ക് നിങ്ങളുടെ അഡ്മിനെ ബന്ധപ്പെടുക"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ടെതറിംഗ് അല്ലെങ്കിൽ ഹോട്ട്സ്പോട്ട് സജീവമാണ്"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"സജ്ജീകരിക്കാൻ ടാപ്പ് ചെയ്യുക."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ടെതറിംഗ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"വിശദാംശങ്ങൾക്ക് നിങ്ങളുടെ അഡ്മിനെ ബന്ധപ്പെടുക"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ഹോട്ട്സ്പോട്ടിന്റെയും ടെതറിംഗിന്റെയും നില"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-mn/strings.xml b/packages/Tethering/res/values-mn/strings.xml index 4596577c5d95..42d1edbaceb9 100644 --- a/packages/Tethering/res/values-mn/strings.xml +++ b/packages/Tethering/res/values-mn/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Модем болгох эсвэл идэвхтэй цэг болгох"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Тохируулахын тулд товшино уу."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Модем болгох боломжгүй байна"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Модем болгох эсвэл сүлжээний цэг идэвхтэй байна"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Тохируулахын тулд товшино уу."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Модем болгохыг идэвхгүй болгосон"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Сүлжээний цэг болон модем болгох төлөв"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-mr/strings.xml b/packages/Tethering/res/values-mr/strings.xml index 85c9ade4feee..13995b6b8aa5 100644 --- a/packages/Tethering/res/values-mr/strings.xml +++ b/packages/Tethering/res/values-mr/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग किंवा हॉटस्पॉट सक्रिय"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करण्यासाठी टॅप करा."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग बंद आहे"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"तपशीलांसाठी तुमच्या प्रशासकाशी संपर्क साधा"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिंग किंवा हॉटस्पॉट अॅक्टिव्ह आहे"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"सेट करण्यासाठी टॅप करा."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिंग बंद केले आहे"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"तपशीलांसाठी तुमच्या ॲडमिनशी संपर्क साधा"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हॉटस्पॉट आणि टेदरिंगची स्थिती"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ms/strings.xml b/packages/Tethering/res/values-ms/strings.xml index ec6bdbda08e7..d6a67f37b1de 100644 --- a/packages/Tethering/res/values-ms/strings.xml +++ b/packages/Tethering/res/values-ms/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Penambatan atau titik panas aktif"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Ketik untuk membuat persediaan."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Penambatan dilumpuhkan"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi pentadbir anda untuk maklumat lanjut"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Penambatan atau tempat liputan aktif"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ketik untuk membuat persediaan."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Penambatan dilumpuhkan"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi pentadbir anda untuk mendapatkan maklumat lanjut"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status tempat liputan & penambatan"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-my/strings.xml b/packages/Tethering/res/values-my/strings.xml index 83978b67d433..49f6b88a7514 100644 --- a/packages/Tethering/res/values-my/strings.xml +++ b/packages/Tethering/res/values-my/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"တဆင့်ပြန်လည်လွှင့်ခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"မိုဘိုင်းဖုန်းကို မိုဒမ်အဖြစ်သုံးခြင်းအား ပိတ်ထားသည်"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"အသေးစိတ်အချက်အလက်များအတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းကို ပိတ်ထားသည်"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"အသေးစိတ်အတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ဟော့စပေါ့နှင့် မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း အခြေအနေ"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-nb/strings.xml b/packages/Tethering/res/values-nb/strings.xml index 9abf32dd7bf1..9594e0a70a69 100644 --- a/packages/Tethering/res/values-nb/strings.xml +++ b/packages/Tethering/res/values-nb/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Internettdeling eller trådløs sone er aktiv"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Trykk for å konfigurere."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internettdeling er slått av"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ta kontakt med administratoren din for å få mer informasjon"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Internettdeling eller Wi-Fi-sone er aktiv"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Trykk for å konfigurere."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internettdeling er slått av"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ta kontakt med administratoren din for å få mer informasjon"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for Wi-Fi-sone og internettdeling"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ne/strings.xml b/packages/Tethering/res/values-ne/strings.xml index c8869298a546..72ae3a80a928 100644 --- a/packages/Tethering/res/values-ne/strings.xml +++ b/packages/Tethering/res/values-ne/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"टेथर गर्ने वा हटस्पट सक्रिय"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"सेटअप गर्न ट्याप गर्नुहोस्।"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिङलाई असक्षम पारिएको छ"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिङ वा हटस्पट सक्रिय छ"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"सेटअप गर्न ट्याप गर्नुहोस्।"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिङ सुविधा असक्षम पारिएको छ"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हटस्पट तथा टेदरिङको स्थिति"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-nl/strings.xml b/packages/Tethering/res/values-nl/strings.xml index 0ec4bff62154..18b2bbfc7670 100644 --- a/packages/Tethering/res/values-nl/strings.xml +++ b/packages/Tethering/res/values-nl/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering of hotspot actief"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om in te stellen."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is uitgeschakeld"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Neem contact op met je beheerder voor meer informatie"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering of hotspot actief"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tik om in te stellen."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is uitgeschakeld"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Neem contact op met je beheerder voor meer informatie"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status van hotspot en tethering"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-or/strings.xml b/packages/Tethering/res/values-or/strings.xml index 457685795a16..a15a6db42af6 100644 --- a/packages/Tethering/res/values-or/strings.xml +++ b/packages/Tethering/res/values-or/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ଟିଥରିଙ୍ଗ କିମ୍ୱା ହଟସ୍ପଟ୍ ସକ୍ରିୟ ଅଛି"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ସେଟଅପ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ଟିଥରିଙ୍ଗ ଅକ୍ଷମ କରାଯାଇଛି"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ବିବରଣୀ ପାଇଁ ନିଜ ଆଡମିନ୍ଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ଟିଥେରିଂ କିମ୍ୱା ହଟସ୍ପଟ୍ ସକ୍ରିୟ ଅଛି"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"ସେଟ୍ ଅପ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ଟିଥେରିଂ ଅକ୍ଷମ କରାଯାଇଛି"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"ବିବରଣୀଗୁଡ଼ିକ ପାଇଁ ଆପଣଙ୍କ ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ହଟସ୍ପଟ୍ ଓ ଟିଥେରିଂ ସ୍ଥିତି"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-pa/strings.xml b/packages/Tethering/res/values-pa/strings.xml index deddf2ea27f7..a8235e423e47 100644 --- a/packages/Tethering/res/values-pa/strings.xml +++ b/packages/Tethering/res/values-pa/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ਟੈਦਰਿੰਗ ਜਾਂ ਹੌਟਸਪੌਟ ਕਿਰਿਆਸ਼ੀਲ"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ਟੈਦਰਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ਟੈਦਰਿੰਗ ਜਾਂ ਹੌਟਸਪੌਟ ਕਿਰਿਆਸ਼ੀਲ"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ਟੈਦਰਿੰਗ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ਹੌਟਸਪੌਟ ਅਤੇ ਟੈਦਰਿੰਗ ਦੀ ਸਥਿਤੀ"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-pl/strings.xml b/packages/Tethering/res/values-pl/strings.xml index 48d8468935a1..ccb017d43fa8 100644 --- a/packages/Tethering/res/values-pl/strings.xml +++ b/packages/Tethering/res/values-pl/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Aktywny tethering lub punkt dostępu"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Kliknij, by skonfigurować."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering został wyłączony"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Aktywny tethering lub punkt dostępu"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Kliknij, by skonfigurować"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering został wyłączony"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot i tethering – stan"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-pt-rBR/strings.xml b/packages/Tethering/res/values-pt-rBR/strings.xml index 32c22b8713b5..a0a4745f9394 100644 --- a/packages/Tethering/res/values-pt-rBR/strings.xml +++ b/packages/Tethering/res/values-pt-rBR/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-pt-rPT/strings.xml b/packages/Tethering/res/values-pt-rPT/strings.xml index 641e22f44f25..e3f03fcc6934 100644 --- a/packages/Tethering/res/values-pt-rPT/strings.xml +++ b/packages/Tethering/res/values-pt-rPT/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Ligação ponto a ponto ou hotspot activos"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"A ligação (à Internet) via telemóvel está desativada."</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacte o gestor para obter detalhes."</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Ligação (à Internet) via telemóvel ou zona Wi-Fi ativas"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"A ligação (à Internet) via telemóvel está desativada."</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacte o administrador para obter detalhes."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona Wi-Fi e da ligação (à Internet) via telemóvel"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-pt/strings.xml b/packages/Tethering/res/values-pt/strings.xml index 32c22b8713b5..a0a4745f9394 100644 --- a/packages/Tethering/res/values-pt/strings.xml +++ b/packages/Tethering/res/values-pt/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ro/strings.xml b/packages/Tethering/res/values-ro/strings.xml index f861f733b4a1..5706a4a69c79 100644 --- a/packages/Tethering/res/values-ro/strings.xml +++ b/packages/Tethering/res/values-ro/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering sau hotspot activ"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Atingeți ca să configurați."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tetheringul este dezactivat"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contactați administratorul pentru detalii"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering sau hotspot activ"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Atingeți ca să configurați."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tetheringul este dezactivat"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contactați administratorul pentru detalii"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Starea hotspotului și a tetheringului"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ru/strings.xml b/packages/Tethering/res/values-ru/strings.xml index 027cb410c54c..7cb6f7db3fc8 100644 --- a/packages/Tethering/res/values-ru/strings.xml +++ b/packages/Tethering/res/values-ru/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Включен режим модема"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Нажмите, чтобы настроить."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Включить режим модема нельзя"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Обратитесь к администратору, чтобы узнать подробности."</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Включен режим модема или точка доступа"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Нажмите, чтобы настроить."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Использование телефона в качестве модема запрещено"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Чтобы узнать подробности, обратитесь к администратору."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хот-спота и режима модема"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-si/strings.xml b/packages/Tethering/res/values-si/strings.xml index 7d8599f2c2d9..ec34c22de750 100644 --- a/packages/Tethering/res/values-si/strings.xml +++ b/packages/Tethering/res/values-si/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ටෙදරින් හෝ හොට්ස්පොට් සක්රීයයි"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"පිහිටුවීමට තට්ටු කරන්න."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ටෙදරින් අබල කර ඇත"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ටෙදරින් හෝ හොට්ස්පොට් සක්රීයයි"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"පිහිටුවීමට තට්ටු කරන්න."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ටෙදරින් අබල කර ඇත"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"හොට්ස්පොට් & ටෙදරින් තත්ත්වය"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-sk/strings.xml b/packages/Tethering/res/values-sk/strings.xml index a8fe297c0088..43e787c84f87 100644 --- a/packages/Tethering/res/values-sk/strings.xml +++ b/packages/Tethering/res/values-sk/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering alebo prístupový bod je aktívny"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím prejdete na nastavenie."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je deaktivovaný"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požiadajte svojho správcu"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering alebo prístupový bod je aktívny"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím prejdete na nastavenie."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je deaktivovaný"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požiadajte svojho správcu"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-sl/strings.xml b/packages/Tethering/res/values-sl/strings.xml index b5e5e3856f7b..59433626a115 100644 --- a/packages/Tethering/res/values-sl/strings.xml +++ b/packages/Tethering/res/values-sl/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivna povezava z internetom ali dostopna točka sta aktivni"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Dotaknite se, če želite nastaviti."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezava z internetom prek mobilnega telefona je onemogočena"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Za podrobnosti se obrnite na skrbnika"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Povezava z internetom prek mobilnega telefona ali dostopna točka je aktivna"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Dotaknite se, če želite nastaviti."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezava z internetom prek mobilnega telefona je onemogočena"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Za podrobnosti se obrnite na skrbnika"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stanje dostopne točke in povezave z internetom prek mobilnega telefona"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-sq/strings.xml b/packages/Tethering/res/values-sq/strings.xml index fdd4906cc51e..21e11558bb0b 100644 --- a/packages/Tethering/res/values-sq/strings.xml +++ b/packages/Tethering/res/values-sq/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Lidhja e çiftimit ose ajo e qasjes në zona publike interneti është aktive"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Trokit për ta konfiguruar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Lidhja e çiftimit është çaktivizuar"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakto me administratorin për detaje"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Ndarja e internetit ose zona e qasjes së internetit është aktive"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Trokit për ta konfiguruar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ndarja e internetit është çaktivizuar"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakto me administratorin për detaje"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Statusi i zonës së qasjes dhe ndarjes së internetit"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-sr/strings.xml b/packages/Tethering/res/values-sr/strings.xml index 9fab34589724..e2e4dc6361d4 100644 --- a/packages/Tethering/res/values-sr/strings.xml +++ b/packages/Tethering/res/values-sr/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Активно повезивање са интернетом преко мобилног уређаја или хотспот"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Додирните да бисте подесили."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Привезивање је онемогућено"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Потражите детаље од администратора"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Привезивање или хотспот је активан"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Додирните да бисте подесили."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Привезивање је онемогућено"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Потражите детаље од администратора"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хотспота и привезивања"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-sv/strings.xml b/packages/Tethering/res/values-sv/strings.xml index 10eeb0fe12e1..72702c28587d 100644 --- a/packages/Tethering/res/values-sv/strings.xml +++ b/packages/Tethering/res/values-sv/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Internetdelning eller surfzon aktiverad"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tryck om du vill konfigurera."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internetdelning har inaktiverats"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakta administratören om du vill veta mer"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Internetdelning eller surfzon har aktiverats"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tryck om du vill konfigurera."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internetdelning har inaktiverats"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakta administratören om du vill veta mer"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trådlös surfzon och internetdelning har inaktiverats"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-sw/strings.xml b/packages/Tethering/res/values-sw/strings.xml index 335396307730..65e4aa8cebb0 100644 --- a/packages/Tethering/res/values-sw/strings.xml +++ b/packages/Tethering/res/values-sw/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Kushiriki au kusambaza intaneti kumewashwa"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Gusa ili uweke mipangilio."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Umezima kipengele cha kusambaza mtandao"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Kusambaza mtandao au mtandaopepe umewashwa"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Gusa ili uweke mipangilio."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Umezima kipengele cha kusambaza mtandao"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Mtandaopepe na hali ya kusambaza mtandao"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ta/strings.xml b/packages/Tethering/res/values-ta/strings.xml index b1e5cc241376..4aba62d4ab46 100644 --- a/packages/Tethering/res/values-ta/strings.xml +++ b/packages/Tethering/res/values-ta/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"டெதெரிங்/ஹாட்ஸ்பாட் இயங்குகிறது"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"அமைக்க, தட்டவும்."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"இணைப்பு முறை முடக்கப்பட்டுள்ளது"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"விவரங்களுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"டெதெரிங் அல்லது ஹாட்ஸ்பாட் இயங்குகிறது"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"அமைக்க, தட்டவும்."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"டெதெரிங் முடக்கப்பட்டுள்ளது"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"விவரங்களுக்கு உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ஹாட்ஸ்பாட் & டெதெரிங் நிலை"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-te/strings.xml b/packages/Tethering/res/values-te/strings.xml index aae40dee40db..1f917913416f 100644 --- a/packages/Tethering/res/values-te/strings.xml +++ b/packages/Tethering/res/values-te/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"టీథర్ చేయబడినది లేదా హాట్స్పాట్ సక్రియంగా ఉండేది"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"సెటప్ చేయడానికి నొక్కండి."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"టెథెరింగ్ నిలిపివేయబడింది"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"వివరాల కోసం మీ నిర్వాహకులను సంప్రదించండి"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"టెథరింగ్ లేదా హాట్స్పాట్ యాక్టివ్గా ఉంది"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"సెటప్ చేయడానికి ట్యాప్ చేయండి."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"టెథరింగ్ డిజేబుల్ చేయబడింది"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"వివరాల కోసం మీ అడ్మిన్ని సంప్రదించండి"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"హాట్స్పాట్ & టెథరింగ్ స్థితి"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-th/strings.xml b/packages/Tethering/res/values-th/strings.xml index 1b800565ad1f..44171c0db82f 100644 --- a/packages/Tethering/res/values-th/strings.xml +++ b/packages/Tethering/res/values-th/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"การปล่อยสัญญาณหรือฮอตสปอตทำงานอยู่"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"แตะเพื่อตั้งค่า"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือหรือฮอตสปอตทำงานอยู่"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"แตะเพื่อตั้งค่า"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"สถานะฮอตสปอตและการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-tl/strings.xml b/packages/Tethering/res/values-tl/strings.xml index 12863f90e15a..7347dd3e6254 100644 --- a/packages/Tethering/res/values-tl/strings.xml +++ b/packages/Tethering/res/values-tl/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Pagsasama o aktibong hotspot"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"I-tap upang i-set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Naka-disable ang pag-tether"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Aktibo ang pag-tether o hotspot"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"I-tap para i-set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Naka-disable ang pag-tether"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status ng hotspot at pag-tether"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-tr/strings.xml b/packages/Tethering/res/values-tr/strings.xml index bfcf1ace2cf7..32030f176574 100644 --- a/packages/Tethering/res/values-tr/strings.xml +++ b/packages/Tethering/res/values-tr/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering veya hotspot etkin"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Ayarlamak için dokunun."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering devre dışı bırakıldı"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ayrıntılı bilgi için yöneticinize başvurun"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering veya hotspot etkin"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamak için dokunun."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering devre dışı bırakıldı"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ayrıntılı bilgi için yöneticinize başvurun"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot ve tethering durumu"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-uk/strings.xml b/packages/Tethering/res/values-uk/strings.xml index 8e159c072350..1ca89b3f7813 100644 --- a/packages/Tethering/res/values-uk/strings.xml +++ b/packages/Tethering/res/values-uk/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Прив\'язка чи точка дост. активна"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Торкніться, щоб налаштувати."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Використання телефона в режимі модема вимкнено"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Щоб дізнатися більше, зв’яжіться з адміністратором"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Модем чи точка доступу активні"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Натисніть, щоб налаштувати."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Використання телефона як модема вимкнено"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Щоб дізнатися більше, зв\'яжіться з адміністратором"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус точки доступу та модема"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-ur/strings.xml b/packages/Tethering/res/values-ur/strings.xml index 89195d4aae29..d72c7d419577 100644 --- a/packages/Tethering/res/values-ur/strings.xml +++ b/packages/Tethering/res/values-ur/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ٹیدرنگ یا ہاٹ اسپاٹ فعال"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ٹیدرنگ غیر فعال ہے"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"تفصیلات کے لئے اپنے منتظم سے رابطہ کریں"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ٹیدرنگ یا ہاٹ اسپاٹ فعال"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ٹیدرنگ غیر فعال ہے"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"تفصیلات کے لئے اپنے منتظم سے رابطہ کریں"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ہاٹ اسپاٹ اور ٹیتھرنگ کا اسٹیٹس"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-uz/strings.xml b/packages/Tethering/res/values-uz/strings.xml index 0ac4d4a7410a..af3b2ebb3500 100644 --- a/packages/Tethering/res/values-uz/strings.xml +++ b/packages/Tethering/res/values-uz/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Modem rejimi yoniq"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Sozlash uchun bosing."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modem rejimi faolsizlantirildi"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Tafsilotlari uchun administratoringizga murojaat qiling"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Modem rejimi yoki hotspot yoniq"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Sozlash uchun bosing."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modem rejimi faolsizlantirildi"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Tafsilotlari uchun administratoringizga murojaat qiling"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot va modem rejimi holati"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-vi/strings.xml b/packages/Tethering/res/values-vi/strings.xml index 85a4db8aa5da..21a0735922c3 100644 --- a/packages/Tethering/res/values-vi/strings.xml +++ b/packages/Tethering/res/values-vi/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Chức năng điểm truy cập Internet hoặc điểm phát sóng đang hoạt động"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Nhấn để thiết lập."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Đã tắt tính năng chia sẻ kết nối"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tính năng chia sẻ Internet hoặc điểm phát sóng đang hoạt động"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Hãy nhấn để thiết lập."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Đã tắt tính năng chia sẻ Internet"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trạng thái điểm phát sóng và chia sẻ Internet"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-zh-rCN/strings.xml b/packages/Tethering/res/values-zh-rCN/strings.xml index ff1fe039531c..98e3b4b46fdb 100644 --- a/packages/Tethering/res/values-zh-rCN/strings.xml +++ b/packages/Tethering/res/values-zh-rCN/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"网络共享或热点已启用"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"点按即可进行设置。"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"网络共享已停用"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"请与您的管理员联系以了解详情"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"网络共享或热点已启用"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"点按即可设置。"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"网络共享已停用"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"如需了解详情,请与您的管理员联系"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"热点和网络共享状态"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-zh-rHK/strings.xml b/packages/Tethering/res/values-zh-rHK/strings.xml index 0de39fac97f8..9cafd42dd43f 100644 --- a/packages/Tethering/res/values-zh-rHK/strings.xml +++ b/packages/Tethering/res/values-zh-rHK/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"已啟用網絡共享或熱點"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"輕按即可設定。"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"網絡共享已停用"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"請聯絡您的管理員以瞭解詳情"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"網絡共享或熱點已啟用"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"輕按即可設定。"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"網絡共享已停用"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"請聯絡您的管理員以瞭解詳情"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"熱點和網絡共享狀態"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-zh-rTW/strings.xml b/packages/Tethering/res/values-zh-rTW/strings.xml index 9a117bbca43f..9d738a76eb0e 100644 --- a/packages/Tethering/res/values-zh-rTW/strings.xml +++ b/packages/Tethering/res/values-zh-rTW/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"網路共用或無線基地台已啟用"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"輕觸即可進行設定。"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"數據連線已停用"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳情請洽你的管理員"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"數據連線或無線基地台已啟用"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"輕觸即可進行設定。"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"數據連線已停用"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳情請洽你的管理員"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"無線基地台與數據連線狀態"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values-zu/strings.xml b/packages/Tethering/res/values-zu/strings.xml index 8fe10d86cb03..f210f8726ee5 100644 --- a/packages/Tethering/res/values-zu/strings.xml +++ b/packages/Tethering/res/values-zu/strings.xml @@ -1,8 +1,29 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Thepha ukuze usethe."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Thepha ukuze usethe."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"I-Hotspot nesimo sokusebenzisa ifoni njengemodemu"</string> + <string name="no_upstream_notification_title" msgid="1204601824631788482"></string> + <string name="no_upstream_notification_message" msgid="8586582938243032621"></string> + <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string> + <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string> + <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string> </resources> diff --git a/packages/Tethering/res/values/config.xml b/packages/Tethering/res/values/config.xml index 66fbefca9456..83c99d22fda7 100644 --- a/packages/Tethering/res/values/config.xml +++ b/packages/Tethering/res/values/config.xml @@ -158,51 +158,6 @@ <!-- ComponentName of the service used to run no ui tether provisioning. --> <string translatable="false" name="config_wifi_tether_enable">com.android.settings/.wifi.tether.TetherService</string> - <!-- Enable tethering notification --> - <!-- Icons for showing tether enable notification. - Each item should have two elements and be separated with ";". - - The first element is downstream types which is one of tethering. This element has to be - made by WIFI, USB, BT, and OR'd with the others. Use "|" to combine multiple downstream - types and use "," to separate each combinations. Such as - - USB|BT,WIFI|USB|BT - - The second element is icon for the item. This element has to be composed by - <package name>:drawable/<resource name>. Such as - - 1. com.android.networkstack.tethering:drawable/stat_sys_tether_general - 2. android:drawable/xxx - - So the entire string of each item would be - - USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general - - NOTE: One config can be separated into two or more for readability. Such as - - WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;android:drawable/xxx - - can be separated into - - WIFI|USB;android:drawable/xxx - WIFI|BT;android:drawable/xxx - USB|BT;android:drawable/xxx - WIFI|USB|BT;android:drawable/xxx - - Notification will not show if the downstream type isn't listed in array. - Empty array means disable notifications. --> - <!-- In AOSP, hotspot is configured to no notification by default. Because status bar has showed - an icon on the right side already --> - <string-array translatable="false" name="tethering_notification_icons"> - <item>USB;com.android.networkstack.tethering:drawable/stat_sys_tether_usb</item> - <item>BT;com.android.networkstack.tethering:drawable/stat_sys_tether_bluetooth</item> - <item>WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general</item> - </string-array> - <!-- String for tether enable notification title. --> - <string name="tethering_notification_title">@string/tethered_notification_title</string> - <!-- String for tether enable notification message. --> - <string name="tethering_notification_message">@string/tethered_notification_message</string> - <!-- No upstream notification is shown when there is a downstream but no upstream that is able to do the tethering. --> <!-- Delay(millisecond) to show no upstream notification after there's no Backhaul. Set delay to diff --git a/packages/Tethering/res/values/overlayable.xml b/packages/Tethering/res/values/overlayable.xml index bbba3f30a292..16ae8ade19da 100644 --- a/packages/Tethering/res/values/overlayable.xml +++ b/packages/Tethering/res/values/overlayable.xml @@ -32,44 +32,6 @@ <item type="string" name="config_mobile_hotspot_provision_response"/> <item type="integer" name="config_mobile_hotspot_provision_check_period"/> <item type="string" name="config_wifi_tether_enable"/> - <!-- Configuration values for TetheringNotificationUpdater --> - <!-- Icons for showing tether enable notification. - Each item should have two elements and be separated with ";". - - The first element is downstream types which is one of tethering. This element has to be - made by WIFI, USB, BT, and OR'd with the others. Use "|" to combine multiple downstream - types and use "," to separate each combinations. Such as - - USB|BT,WIFI|USB|BT - - The second element is icon for the item. This element has to be composed by - <package name>:drawable/<resource name>. Such as - - 1. com.android.networkstack.tethering:drawable/stat_sys_tether_general - 2. android:drawable/xxx - - So the entire string of each item would be - - USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general - - NOTE: One config can be separated into two or more for readability. Such as - - WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;android:drawable/xxx - - can be separated into - - WIFI|USB;android:drawable/xxx - WIFI|BT;android:drawable/xxx - USB|BT;android:drawable/xxx - WIFI|USB|BT;android:drawable/xxx - - Notification will not show if the downstream type isn't listed in array. - Empty array means disable notifications. --> - <item type="array" name="tethering_notification_icons"/> - <!-- String for tether enable notification title. --> - <item type="string" name="tethering_notification_title"/> - <!-- String for tether enable notification message. --> - <item type="string" name="tethering_notification_message"/> <!-- Params from config.xml that can be overlaid --> </policy> </overlayable> diff --git a/packages/Tethering/res/values/strings.xml b/packages/Tethering/res/values/strings.xml index 4fa60d412566..d63c7c5063cc 100644 --- a/packages/Tethering/res/values/strings.xml +++ b/packages/Tethering/res/values/strings.xml @@ -19,9 +19,6 @@ <string name="tethered_notification_title">Tethering or hotspot active</string> <!-- String for tethered notification message [CHAR LIMIT=200] --> <string name="tethered_notification_message">Tap to set up.</string> - <!-- String for tethered notification title with client number info. --> - <plurals name="tethered_notification_title_with_client_number"> - </plurals> <!-- This notification is shown when tethering has been disabled on a user's device. The device is managed by the user's employer. Tethering can't be turned on unless the @@ -47,6 +44,4 @@ <string name="upstream_roaming_notification_title"></string> <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> <string name="upstream_roaming_notification_message"></string> - <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> - <string name="upstream_roaming_notification_continue_button"></string> </resources> diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java index 85a23fb83fb2..55344fc75d65 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java @@ -142,7 +142,7 @@ public class OffloadHardwareInterface { public boolean initOffloadConfig() { IOffloadConfig offloadConfig; try { - offloadConfig = IOffloadConfig.getService(); + offloadConfig = IOffloadConfig.getService(true /*retry*/); } catch (RemoteException e) { mLog.e("getIOffloadConfig error " + e); return false; diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java index 05cf68efd755..4e16c49caa0e 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -1007,6 +1007,11 @@ public class Tethering { } @VisibleForTesting + boolean isTetheringActive() { + return mActiveTetheringRequests.size() > 0; + } + + @VisibleForTesting protected static class UserRestrictionActionListener { private final UserManager mUserManager; private final Tethering mWrapper; @@ -1043,13 +1048,14 @@ public class Tethering { return; } - // Restricted notification is shown when tethering function is disallowed on - // user's device. - mNotificationUpdater.notifyTetheringDisabledByRestriction(); - - // Untether from all downstreams since tethering is disallowed. - mWrapper.untetherAll(); + if (mWrapper.isTetheringActive()) { + // Restricted notification is shown when tethering function is disallowed on + // user's device. + mNotificationUpdater.notifyTetheringDisabledByRestriction(); + // Untether from all downstreams since tethering is disallowed. + mWrapper.untetherAll(); + } // TODO(b/148139325): send tetheringSupported on restriction change } } diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java index f490cc4719fa..d03deda37fdf 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java @@ -17,9 +17,6 @@ package com.android.networkstack.tethering; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; -import static android.net.TetheringManager.TETHERING_BLUETOOTH; -import static android.net.TetheringManager.TETHERING_USB; -import static android.net.TetheringManager.TETHERING_WIFI; import static android.text.TextUtils.isEmpty; import android.app.Notification; @@ -39,10 +36,8 @@ import android.os.UserHandle; import android.provider.Settings; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; -import android.util.Log; import android.util.SparseArray; -import androidx.annotation.ArrayRes; import androidx.annotation.DrawableRes; import androidx.annotation.IntDef; import androidx.annotation.IntRange; @@ -77,9 +72,6 @@ public class TetheringNotificationUpdater { private static final boolean NO_NOTIFY = false; @VisibleForTesting static final int EVENT_SHOW_NO_UPSTREAM = 1; - // Id to update and cancel enable notification. Must be unique within the tethering app. - @VisibleForTesting - static final int ENABLE_NOTIFICATION_ID = 1000; // Id to update and cancel restricted notification. Must be unique within the tethering app. @VisibleForTesting static final int RESTRICTED_NOTIFICATION_ID = 1001; @@ -120,7 +112,6 @@ public class TetheringNotificationUpdater { @Retention(RetentionPolicy.SOURCE) @IntDef(value = { - ENABLE_NOTIFICATION_ID, RESTRICTED_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID @@ -223,7 +214,6 @@ public class TetheringNotificationUpdater { final boolean tetheringActiveChanged = (downstreamTypes == DOWNSTREAM_NONE) != (mDownstreamTypesMask == DOWNSTREAM_NONE); final boolean subIdChanged = subId != mActiveDataSubId; - final boolean downstreamChanged = downstreamTypes != mDownstreamTypesMask; final boolean upstreamChanged = noUpstream != mNoUpstream; final boolean roamingChanged = isRoaming != mRoaming; final boolean updateAll = tetheringActiveChanged || subIdChanged; @@ -232,19 +222,10 @@ public class TetheringNotificationUpdater { mNoUpstream = noUpstream; mRoaming = isRoaming; - if (updateAll || downstreamChanged) updateEnableNotification(); if (updateAll || upstreamChanged) updateNoUpstreamNotification(); if (updateAll || roamingChanged) updateRoamingNotification(); } - private void updateEnableNotification() { - final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE; - - if (tetheringInactive || setupNotification() == NO_NOTIFY) { - clearNotification(ENABLE_NOTIFICATION_ID); - } - } - private void updateNoUpstreamNotification() { final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE; @@ -286,7 +267,7 @@ public class TetheringNotificationUpdater { null /* options */); showNotification(R.drawable.stat_sys_tether_general, title, message, - RESTRICTED_NOTIFICATION_ID, pi, new Action[0]); + RESTRICTED_NOTIFICATION_ID, false /* ongoing */, pi, new Action[0]); } private void notifyTetheringNoUpstream() { @@ -307,65 +288,7 @@ public class TetheringNotificationUpdater { final Action action = new Action.Builder(NO_ICON_ID, disableButton, pi).build(); showNotification(R.drawable.stat_sys_tether_general, title, message, - NO_UPSTREAM_NOTIFICATION_ID, null /* pendingIntent */, action); - } - - /** - * Returns the downstream types mask which convert from given string. - * - * @param types This string has to be made by "WIFI", "USB", "BT", and OR'd with the others. - * - * @return downstream types mask value. - */ - @VisibleForTesting - @IntRange(from = 0, to = 7) - int getDownstreamTypesMask(@NonNull final String types) { - int downstreamTypesMask = DOWNSTREAM_NONE; - final String[] downstreams = types.split("\\|"); - for (String downstream : downstreams) { - if (USB_DOWNSTREAM.equals(downstream.trim())) { - downstreamTypesMask |= (1 << TETHERING_USB); - } else if (WIFI_DOWNSTREAM.equals(downstream.trim())) { - downstreamTypesMask |= (1 << TETHERING_WIFI); - } else if (BLUETOOTH_DOWNSTREAM.equals(downstream.trim())) { - downstreamTypesMask |= (1 << TETHERING_BLUETOOTH); - } - } - return downstreamTypesMask; - } - - /** - * Returns the icons {@link android.util.SparseArray} which get from given string-array resource - * id. - * - * @param id String-array resource id - * - * @return {@link android.util.SparseArray} with downstream types and icon id info. - */ - @NonNull - @VisibleForTesting - SparseArray<Integer> getIcons(@ArrayRes int id, @NonNull Resources res) { - final String[] array = res.getStringArray(id); - final SparseArray<Integer> icons = new SparseArray<>(); - for (String config : array) { - if (isEmpty(config)) continue; - - final String[] elements = config.split(";"); - if (elements.length != 2) { - Log.wtf(TAG, - "Unexpected format in Tethering notification configuration : " + config); - continue; - } - - final String[] types = elements[0].split(","); - for (String type : types) { - int mask = getDownstreamTypesMask(type); - if (mask == DOWNSTREAM_NONE) continue; - icons.put(mask, res.getIdentifier( - elements[1].trim(), null /* defType */, null /* defPackage */)); - } - } - return icons; + NO_UPSTREAM_NOTIFICATION_ID, true /* ongoing */, null /* pendingIntent */, action); } private boolean setupRoamingNotification() { @@ -387,7 +310,7 @@ public class TetheringNotificationUpdater { null /* options */); showNotification(R.drawable.stat_sys_tether_general, title, message, - ROAMING_NOTIFICATION_ID, pi, new Action[0]); + ROAMING_NOTIFICATION_ID, true /* ongoing */, pi, new Action[0]); return NOTIFY_DONE; } @@ -403,38 +326,15 @@ public class TetheringNotificationUpdater { return NOTIFY_DONE; } - private boolean setupNotification() { - final Resources res = getResourcesForSubId(mContext, mActiveDataSubId); - final SparseArray<Integer> downstreamIcons = - getIcons(R.array.tethering_notification_icons, res); - - final int iconId = downstreamIcons.get(mDownstreamTypesMask, NO_ICON_ID); - if (iconId == NO_ICON_ID) return NO_NOTIFY; - - final String title = res.getString(R.string.tethering_notification_title); - final String message = res.getString(R.string.tethering_notification_message); - if (isEmpty(title) || isEmpty(message)) return NO_NOTIFY; - - final PendingIntent pi = PendingIntent.getActivity( - mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), - 0 /* requestCode */, - new Intent(Settings.ACTION_TETHER_SETTINGS), - Intent.FLAG_ACTIVITY_NEW_TASK, - null /* options */); - - showNotification(iconId, title, message, ENABLE_NOTIFICATION_ID, pi, new Action[0]); - return NOTIFY_DONE; - } - private void showNotification(@DrawableRes final int iconId, @NonNull final String title, - @NonNull final String message, @NotificationId final int id, @Nullable PendingIntent pi, - @NonNull final Action... actions) { + @NonNull final String message, @NotificationId final int id, final boolean ongoing, + @Nullable PendingIntent pi, @NonNull final Action... actions) { final Notification notification = new Notification.Builder(mContext, mChannel.getId()) .setSmallIcon(iconId) .setContentTitle(title) .setContentText(message) - .setOngoing(true) + .setOngoing(ongoing) .setColor(mContext.getColor( android.R.color.system_notification_accent_color)) .setVisibility(Notification.VISIBILITY_PUBLIC) diff --git a/packages/Tethering/tests/integration/Android.bp b/packages/Tethering/tests/integration/Android.bp index 6b751afdf58b..3305ed084481 100644 --- a/packages/Tethering/tests/integration/Android.bp +++ b/packages/Tethering/tests/integration/Android.bp @@ -69,6 +69,7 @@ android_test { test_config: "AndroidTest_Coverage.xml", defaults: ["libnetworkstackutilsjni_deps"], static_libs: [ + "NetworkStaticLibTestsLib", "NetworkStackTestsLib", "TetheringTestsLib", "TetheringIntegrationTestsLib", diff --git a/packages/Tethering/tests/unit/Android.bp b/packages/Tethering/tests/unit/Android.bp index 26517ceb72ae..08cfb30813ca 100644 --- a/packages/Tethering/tests/unit/Android.bp +++ b/packages/Tethering/tests/unit/Android.bp @@ -14,6 +14,26 @@ // limitations under the License. // +// Tests in this folder are included both in unit tests and CTS. +java_library { + name: "TetheringCommonTests", + srcs: [ + "common/**/*.java", + "common/**/*.kt" + ], + static_libs: [ + "androidx.test.rules", + "net-tests-utils", + ], + // TODO(b/147200698) change sdk_version to module-current and remove framework-minus-apex + sdk_version: "core_platform", + libs: [ + "framework-minus-apex", + "framework-tethering", + ], + visibility: ["//cts/tests/tests/tethering"], +} + java_defaults { name: "TetheringTestsDefaults", srcs: [ @@ -22,6 +42,7 @@ java_defaults { ], static_libs: [ "TetheringApiCurrentLib", + "TetheringCommonTests", "androidx.test.rules", "frameworks-base-testutils", "mockito-target-extended-minus-junit4", diff --git a/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt b/packages/Tethering/tests/unit/common/android/net/TetheredClientTest.kt index a20a0dfd9c89..55c59dd08f41 100644 --- a/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt +++ b/packages/Tethering/tests/unit/common/android/net/TetheredClientTest.kt @@ -33,7 +33,9 @@ private val TEST_MACADDR = MacAddress.fromBytes(byteArrayOf(12, 23, 34, 45, 56, private val TEST_OTHER_MACADDR = MacAddress.fromBytes(byteArrayOf(23, 34, 45, 56, 67, 78)) private val TEST_ADDR1 = makeLinkAddress("192.168.113.3", prefixLength = 24, expTime = 123L) private val TEST_ADDR2 = makeLinkAddress("fe80::1:2:3", prefixLength = 64, expTime = 456L) -private val TEST_ADDRINFO1 = AddressInfo(TEST_ADDR1, "test_hostname") +private val TEST_HOSTNAME = "test_hostname" +private val TEST_OTHER_HOSTNAME = "test_other_hostname" +private val TEST_ADDRINFO1 = AddressInfo(TEST_ADDR1, TEST_HOSTNAME) private val TEST_ADDRINFO2 = AddressInfo(TEST_ADDR2, null) private fun makeLinkAddress(addr: String, prefixLength: Int, expTime: Long) = LinkAddress( @@ -49,6 +51,7 @@ private fun makeLinkAddress(addr: String, prefixLength: Int, expTime: Long) = Li class TetheredClientTest { @Test fun testParceling() { + assertParcelSane(TEST_ADDRINFO1, fieldCount = 2) assertParcelSane(makeTestClient(), fieldCount = 3) } @@ -65,7 +68,7 @@ class TetheredClientTest { // Different hostname assertNotEquals(makeTestClient(), TetheredClient( TEST_MACADDR, - listOf(AddressInfo(TEST_ADDR1, "test_other_hostname"), TEST_ADDRINFO2), + listOf(AddressInfo(TEST_ADDR1, TEST_OTHER_HOSTNAME), TEST_ADDRINFO2), TETHERING_BLUETOOTH)) // Null hostname @@ -97,6 +100,21 @@ class TetheredClientTest { TETHERING_USB), client1.addAddresses(client2)) } + @Test + fun testGetters() { + assertEquals(TEST_MACADDR, makeTestClient().macAddress) + assertEquals(listOf(TEST_ADDRINFO1, TEST_ADDRINFO2), makeTestClient().addresses) + assertEquals(TETHERING_BLUETOOTH, makeTestClient().tetheringType) + } + + @Test + fun testAddressInfo_Getters() { + assertEquals(TEST_ADDR1, TEST_ADDRINFO1.address) + assertEquals(TEST_ADDR2, TEST_ADDRINFO2.address) + assertEquals(TEST_HOSTNAME, TEST_ADDRINFO1.hostname) + assertEquals(null, TEST_ADDRINFO2.hostname) + } + private fun makeTestClient() = TetheredClient( TEST_MACADDR, listOf(TEST_ADDRINFO1, TEST_ADDRINFO2), diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt index 04f31a7a2880..745468fdf378 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt @@ -20,8 +20,6 @@ import android.app.Notification import android.app.NotificationManager import android.content.Context import android.content.res.Resources -import android.net.ConnectivityManager.TETHERING_BLUETOOTH -import android.net.ConnectivityManager.TETHERING_USB import android.net.ConnectivityManager.TETHERING_WIFI import android.os.Handler import android.os.HandlerThread @@ -29,14 +27,12 @@ import android.os.Looper import android.net.NetworkCapabilities import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING import android.os.UserHandle -import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import android.telephony.TelephonyManager import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 import com.android.internal.util.test.BroadcastInterceptingContext import com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE -import com.android.networkstack.tethering.TetheringNotificationUpdater.ENABLE_NOTIFICATION_ID import com.android.networkstack.tethering.TetheringNotificationUpdater.EVENT_SHOW_NO_UPSTREAM import com.android.networkstack.tethering.TetheringNotificationUpdater.NO_UPSTREAM_NOTIFICATION_ID import com.android.networkstack.tethering.TetheringNotificationUpdater.RESTRICTED_NOTIFICATION_ID @@ -63,17 +59,9 @@ import org.mockito.Mockito.verifyZeroInteractions import org.mockito.MockitoAnnotations const val TEST_SUBID = 1 -const val WIFI_ICON_ID = 1 -const val USB_ICON_ID = 2 -const val BT_ICON_ID = 3 -const val GENERAL_ICON_ID = 4 const val WIFI_MASK = 1 shl TETHERING_WIFI -const val USB_MASK = 1 shl TETHERING_USB -const val BT_MASK = 1 shl TETHERING_BLUETOOTH -const val TITLE = "Tethering active" -const val MESSAGE = "Tap here to set up." -const val TEST_TITLE = "Hotspot active" -const val TEST_MESSAGE = "Tap to set up hotspot." +const val TEST_DISALLOW_TITLE = "Tether function is disallowed" +const val TEST_DISALLOW_MESSAGE = "Please contact your admin" const val TEST_NO_UPSTREAM_TITLE = "Hotspot has no internet access" const val TEST_NO_UPSTREAM_MESSAGE = "Device cannot connect to internet." const val TEST_NO_UPSTREAM_BUTTON = "Turn off hotspot" @@ -88,7 +76,6 @@ class TetheringNotificationUpdaterTest { @Mock private lateinit var mockContext: Context @Mock private lateinit var notificationManager: NotificationManager @Mock private lateinit var telephonyManager: TelephonyManager - @Mock private lateinit var defaultResources: Resources @Mock private lateinit var testResources: Resources // lateinit for these classes under test, as they should be reset to a different instance for @@ -97,11 +84,6 @@ class TetheringNotificationUpdaterTest { private lateinit var notificationUpdater: TetheringNotificationUpdater private lateinit var fakeTetheringThread: HandlerThread - private val ENABLE_ICON_CONFIGS = arrayOf( - "USB;android.test:drawable/usb", "BT;android.test:drawable/bluetooth", - "WIFI|BT;android.test:drawable/general", "WIFI|USB;android.test:drawable/general", - "USB|BT;android.test:drawable/general", "WIFI|USB|BT;android.test:drawable/general") - private val ROAMING_CAPABILITIES = NetworkCapabilities() private val HOME_CAPABILITIES = NetworkCapabilities().addCapability(NET_CAPABILITY_NOT_ROAMING) private val NOTIFICATION_ICON_ID = R.drawable.stat_sys_tether_general @@ -117,29 +99,19 @@ class TetheringNotificationUpdaterTest { private inner class WrappedNotificationUpdater(c: Context, looper: Looper) : TetheringNotificationUpdater(c, looper) { - override fun getResourcesForSubId(context: Context, subId: Int) = - when (subId) { - TEST_SUBID -> testResources - INVALID_SUBSCRIPTION_ID -> defaultResources - else -> super.getResourcesForSubId(context, subId) - } + override fun getResourcesForSubId(c: Context, subId: Int) = + if (subId == TEST_SUBID) testResources else super.getResourcesForSubId(c, subId) } private fun setupResources() { - doReturn(ENABLE_ICON_CONFIGS).`when`(defaultResources) - .getStringArray(R.array.tethering_notification_icons) - doReturn(arrayOf("WIFI;android.test:drawable/wifi")).`when`(testResources) - .getStringArray(R.array.tethering_notification_icons) doReturn(5).`when`(testResources) .getInteger(R.integer.delay_to_show_no_upstream_after_no_backhaul) doReturn(true).`when`(testResources) .getBoolean(R.bool.config_upstream_roaming_notification) - doReturn(TITLE).`when`(defaultResources).getString(R.string.tethering_notification_title) - doReturn(MESSAGE).`when`(defaultResources) - .getString(R.string.tethering_notification_message) - doReturn(TEST_TITLE).`when`(testResources).getString(R.string.tethering_notification_title) - doReturn(TEST_MESSAGE).`when`(testResources) - .getString(R.string.tethering_notification_message) + doReturn(TEST_DISALLOW_TITLE).`when`(testResources) + .getString(R.string.disable_tether_notification_title) + doReturn(TEST_DISALLOW_MESSAGE).`when`(testResources) + .getString(R.string.disable_tether_notification_message) doReturn(TEST_NO_UPSTREAM_TITLE).`when`(testResources) .getString(R.string.no_upstream_notification_title) doReturn(TEST_NO_UPSTREAM_MESSAGE).`when`(testResources) @@ -150,14 +122,6 @@ class TetheringNotificationUpdaterTest { .getString(R.string.upstream_roaming_notification_title) doReturn(TEST_ROAMING_MESSAGE).`when`(testResources) .getString(R.string.upstream_roaming_notification_message) - doReturn(USB_ICON_ID).`when`(defaultResources) - .getIdentifier(eq("android.test:drawable/usb"), any(), any()) - doReturn(BT_ICON_ID).`when`(defaultResources) - .getIdentifier(eq("android.test:drawable/bluetooth"), any(), any()) - doReturn(GENERAL_ICON_ID).`when`(defaultResources) - .getIdentifier(eq("android.test:drawable/general"), any(), any()) - doReturn(WIFI_ICON_ID).`when`(testResources) - .getIdentifier(eq("android.test:drawable/wifi"), any(), any()) } @Before @@ -206,119 +170,27 @@ class TetheringNotificationUpdaterTest { } @Test - fun testNotificationWithDownstreamChanged() { - // Wifi downstream. No notification. - notificationUpdater.onDownstreamChanged(WIFI_MASK) - verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID)) - - // Same downstream changed. Nothing happened. - notificationUpdater.onDownstreamChanged(WIFI_MASK) - verifyZeroInteractions(notificationManager) - - // Wifi and usb downstreams. Show enable notification - notificationUpdater.onDownstreamChanged(WIFI_MASK or USB_MASK) - verifyNotification(GENERAL_ICON_ID, TITLE, MESSAGE, ENABLE_NOTIFICATION_ID) - - // Usb downstream. Still show enable notification. - notificationUpdater.onDownstreamChanged(USB_MASK) - verifyNotification(USB_ICON_ID, TITLE, MESSAGE, ENABLE_NOTIFICATION_ID) - - // No downstream. No notification. - notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE) - verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID, - ROAMING_NOTIFICATION_ID)) - } - - @Test - fun testNotificationWithActiveDataSubscriptionIdChanged() { - // Usb downstream. Showed enable notification with default resource. - notificationUpdater.onDownstreamChanged(USB_MASK) - verifyNotification(USB_ICON_ID, TITLE, MESSAGE, ENABLE_NOTIFICATION_ID) - - // Same subId changed. Nothing happened. - notificationUpdater.onActiveDataSubscriptionIdChanged(INVALID_SUBSCRIPTION_ID) - verifyZeroInteractions(notificationManager) - - // Set test sub id. Clear notification with test resource. + fun testRestrictedNotification() { + // Set test sub id. notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID) - verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID, - ROAMING_NOTIFICATION_ID)) - - // Wifi downstream. Show enable notification with test resource. - notificationUpdater.onDownstreamChanged(WIFI_MASK) - verifyNotification(WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE, ENABLE_NOTIFICATION_ID) - - // No downstream. No notification. - notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE) - verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID, - ROAMING_NOTIFICATION_ID)) - } - - private fun assertIconNumbers(number: Int, configs: Array<String?>) { - doReturn(configs).`when`(defaultResources) - .getStringArray(R.array.tethering_notification_icons) - assertEquals(number, notificationUpdater.getIcons( - R.array.tethering_notification_icons, defaultResources).size()) - } - - @Test - fun testGetIcons() { - assertIconNumbers(0, arrayOfNulls<String>(0)) - assertIconNumbers(0, arrayOf(null, "")) - assertIconNumbers(3, arrayOf( - // These configurations are invalid with wrong strings or symbols. - ";", ",", "|", "|,;", "WIFI", "1;2", " U SB; ", "bt;", "WIFI;USB;BT", "WIFI|USB|BT", - "WIFI,BT,USB", " WIFI| | | USB, test:drawable/test", - // This configuration is valid with two downstream types (USB, BT). - "USB|,,,,,|BT;drawable/test ", - // This configuration is valid with one downstream types (WIFI). - " WIFI ; android.test:drawable/xxx ")) - } - - @Test - fun testGetDownstreamTypesMask() { - assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("")) - assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("1")) - assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("WIFI_P2P")) - assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("usb")) - assertEquals(WIFI_MASK, notificationUpdater.getDownstreamTypesMask(" WIFI ")) - assertEquals(USB_MASK, notificationUpdater.getDownstreamTypesMask("USB | B T")) - assertEquals(BT_MASK, notificationUpdater.getDownstreamTypesMask(" WIFI: | BT")) - assertEquals(WIFI_MASK or USB_MASK, - notificationUpdater.getDownstreamTypesMask("1|2|USB|WIFI|BLUETOOTH||")) - } - - @Test - fun testSetupRestrictedNotification() { - val title = context.resources.getString(R.string.disable_tether_notification_title) - val message = context.resources.getString(R.string.disable_tether_notification_message) - val disallowTitle = "Tether function is disallowed" - val disallowMessage = "Please contact your admin" - doReturn(title).`when`(defaultResources) - .getString(R.string.disable_tether_notification_title) - doReturn(message).`when`(defaultResources) - .getString(R.string.disable_tether_notification_message) - doReturn(disallowTitle).`when`(testResources) - .getString(R.string.disable_tether_notification_title) - doReturn(disallowMessage).`when`(testResources) - .getString(R.string.disable_tether_notification_message) + verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID)) // User restrictions on. Show restricted notification. notificationUpdater.notifyTetheringDisabledByRestriction() - verifyNotification(NOTIFICATION_ICON_ID, title, message, RESTRICTED_NOTIFICATION_ID) + verifyNotification(NOTIFICATION_ICON_ID, TEST_DISALLOW_TITLE, TEST_DISALLOW_MESSAGE, + RESTRICTED_NOTIFICATION_ID) // User restrictions off. Clear notification. notificationUpdater.tetheringRestrictionLifted() verifyNotificationCancelled(listOf(RESTRICTED_NOTIFICATION_ID)) - // Set test sub id. No notification. - notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID) - verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID, - ROAMING_NOTIFICATION_ID)) + // No downstream. + notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE) + verifyZeroInteractions(notificationManager) - // User restrictions on again. Show restricted notification with test resource. + // User restrictions on again. Show restricted notification. notificationUpdater.notifyTetheringDisabledByRestriction() - verifyNotification(NOTIFICATION_ICON_ID, disallowTitle, disallowMessage, + verifyNotification(NOTIFICATION_ICON_ID, TEST_DISALLOW_TITLE, TEST_DISALLOW_MESSAGE, RESTRICTED_NOTIFICATION_ID) } @@ -356,15 +228,14 @@ class TetheringNotificationUpdaterTest { } @Test - fun testNotificationWithUpstreamCapabilitiesChanged_NoUpstream() { - // Set test sub id. No notification. + fun testNoUpstreamNotification() { + // Set test sub id. notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID) - verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID, - ROAMING_NOTIFICATION_ID)) + verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID)) - // Wifi downstream. Show enable notification with test resource. + // Wifi downstream. notificationUpdater.onDownstreamChanged(WIFI_MASK) - verifyNotification(WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE, ENABLE_NOTIFICATION_ID) + verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID)) // There is no upstream. Show no upstream notification. notificationUpdater.onUpstreamCapabilitiesChanged(null) @@ -386,15 +257,14 @@ class TetheringNotificationUpdaterTest { verifyNotification(NOTIFICATION_ICON_ID, TEST_NO_UPSTREAM_TITLE, TEST_NO_UPSTREAM_MESSAGE, NO_UPSTREAM_NOTIFICATION_ID) - // No downstream. No notification. + // No downstream. notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE) - verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID, - ROAMING_NOTIFICATION_ID)) + verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID)) - // Put up enable notification with wifi downstream and home capabilities. + // Wifi downstream and home capabilities. notificationUpdater.onDownstreamChanged(WIFI_MASK) notificationUpdater.onUpstreamCapabilitiesChanged(HOME_CAPABILITIES) - verifyNotification(WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE, ENABLE_NOTIFICATION_ID) + verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID)) // Set R.integer.delay_to_show_no_upstream_after_no_backhaul to -1 and change to no upstream // again. Don't put up no upstream notification. @@ -429,15 +299,14 @@ class TetheringNotificationUpdaterTest { } @Test - fun testNotificationWithUpstreamCapabilitiesChanged_Roaming() { - // Set test sub id. Clear notification. + fun testRoamingNotification() { + // Set test sub id. notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID) - verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID, - ROAMING_NOTIFICATION_ID)) + verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID)) - // Wifi downstream. Show enable notification with test resource. + // Wifi downstream. notificationUpdater.onDownstreamChanged(WIFI_MASK) - verifyNotification(WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE, ENABLE_NOTIFICATION_ID) + verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID)) // Upstream capabilities changed to roaming state. Show roaming notification. notificationUpdater.onUpstreamCapabilitiesChanged(ROAMING_CAPABILITIES) @@ -464,14 +333,16 @@ class TetheringNotificationUpdaterTest { verifyNotification(NOTIFICATION_ICON_ID, TEST_NO_UPSTREAM_TITLE, TEST_NO_UPSTREAM_MESSAGE, NO_UPSTREAM_NOTIFICATION_ID) - // No downstream. No notification. + // No downstream. notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE) - verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID, - ROAMING_NOTIFICATION_ID)) + verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID)) - // Wifi downstream again. Show enable notification with test resource. + // Wifi downstream again. notificationUpdater.onDownstreamChanged(WIFI_MASK) - verifyNotification(WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE, ENABLE_NOTIFICATION_ID) + notificationUpdater.handler.waitForDelayedMessage(EVENT_SHOW_NO_UPSTREAM, TIMEOUT_MS) + verifyNotificationCancelled(listOf(ROAMING_NOTIFICATION_ID), false) + verifyNotification(NOTIFICATION_ICON_ID, TEST_NO_UPSTREAM_TITLE, TEST_NO_UPSTREAM_MESSAGE, + NO_UPSTREAM_NOTIFICATION_ID) // Set R.bool.config_upstream_roaming_notification to false and change upstream // network to roaming state again. No roaming notification. diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java index cf0548304a78..0c86eeb6cd4d 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java @@ -1079,12 +1079,12 @@ public class TetheringTest { } private void runUserRestrictionsChange( - boolean currentDisallow, boolean nextDisallow, String[] activeTetheringIfacesList, + boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive, int expectedInteractionsWithShowNotification) throws Exception { final Bundle newRestrictions = new Bundle(); newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow); final Tethering mockTethering = mock(Tethering.class); - when(mockTethering.getTetheredIfaces()).thenReturn(activeTetheringIfacesList); + when(mockTethering.isTetheringActive()).thenReturn(isTetheringActive); when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions); final Tethering.UserRestrictionActionListener ural = @@ -1100,63 +1100,63 @@ public class TetheringTest { } @Test - public void testDisallowTetheringWhenNoTetheringInterfaceIsActive() throws Exception { - final String[] emptyActiveIfacesList = new String[]{}; + public void testDisallowTetheringWhenTetheringIsNotActive() throws Exception { + final boolean isTetheringActive = false; final boolean currDisallow = false; final boolean nextDisallow = true; - final int expectedInteractionsWithShowNotification = 1; + final int expectedInteractionsWithShowNotification = 0; - runUserRestrictionsChange(currDisallow, nextDisallow, emptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, expectedInteractionsWithShowNotification); } @Test - public void testDisallowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception { - final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME}; + public void testDisallowTetheringWhenTetheringIsActive() throws Exception { + final boolean isTetheringActive = true; final boolean currDisallow = false; final boolean nextDisallow = true; final int expectedInteractionsWithShowNotification = 1; - runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, expectedInteractionsWithShowNotification); } @Test - public void testAllowTetheringWhenNoTetheringInterfaceIsActive() throws Exception { - final String[] nonEmptyActiveIfacesList = new String[]{}; + public void testAllowTetheringWhenTetheringIsNotActive() throws Exception { + final boolean isTetheringActive = false; final boolean currDisallow = true; final boolean nextDisallow = false; final int expectedInteractionsWithShowNotification = 0; - runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, expectedInteractionsWithShowNotification); } @Test - public void testAllowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception { - final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME}; + public void testAllowTetheringWhenTetheringIsActive() throws Exception { + final boolean isTetheringActive = true; final boolean currDisallow = true; final boolean nextDisallow = false; final int expectedInteractionsWithShowNotification = 0; - runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, expectedInteractionsWithShowNotification); } @Test public void testDisallowTetheringUnchanged() throws Exception { - final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME}; + final boolean isTetheringActive = true; final int expectedInteractionsWithShowNotification = 0; boolean currDisallow = true; boolean nextDisallow = true; - runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, expectedInteractionsWithShowNotification); currDisallow = false; nextDisallow = false; - runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, expectedInteractionsWithShowNotification); } diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml index b0001462bfff..a05a38996ed8 100644 --- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml +++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml @@ -1,29 +1,26 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2019 The Android Open Source Project +<!-- Copyright (C) 2020 The Android Open Source Project - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + 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 + 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. + 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:tint="?android:attr/textColorHint" - android:viewportHeight="24" android:viewportWidth="24" - android:width="24dp" > - <path - android:fillColor="@android:color/white" - android:pathData="M16,4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H2v12c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V6h-6V4z M9.5,4 c0-0.3,0.2-0.5,0.5-0.5h4c0.3,0,0.5,0.2,0.5,0.5v2h-5V4z M20.5,7.5V18c0,0.8-0.7,1.5-1.5,1.5H5c-0.8,0-1.5-0.7-1.5-1.5V7.5H20.5z" /> - <path - android:fillColor="@android:color/white" - android:pathData="M 12 12.3 C 12.6627416998 12.3 13.2 12.8372583002 13.2 13.5 C 13.2 14.1627416998 12.6627416998 14.7 12 14.7 C 11.3372583002 14.7 10.8 14.1627416998 10.8 13.5 C 10.8 12.8372583002 11.3372583002 12.3 12 12.3 Z" /> + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M19.75,6H16c0,0 0,0 0,0c0,-2.05 -0.95,-4 -4,-4C8.96,2 8,3.97 8,6c0,0 0,0 0,0H4.25C3.01,6 2,7.01 2,8.25v10.5C2,19.99 3.01,21 4.25,21h15.5c1.24,0 2.25,-1.01 2.25,-2.25V8.25C22,7.01 20.99,6 19.75,6zM12,3.5c0.54,-0.01 2.5,-0.11 2.5,2.5c0,0 0,0 0,0h-5c0,0 0,0 0,0C9.5,3.39 11.45,3.48 12,3.5zM20.5,18.75c0,0.41 -0.34,0.75 -0.75,0.75H4.25c-0.41,0 -0.75,-0.34 -0.75,-0.75V8.25c0,-0.41 0.34,-0.75 0.75,-0.75h15.5c0.41,0 0.75,0.34 0.75,0.75V18.75z"/> + <path + android:fillColor="#FF000000" + android:pathData="M12,12c-0.05,0 -1.5,-0.09 -1.5,1.5c0,1.59 1.43,1.5 1.5,1.5c0.05,0 1.5,0.09 1.5,-1.5C13.5,11.91 12.07,12 12,12z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp_off.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp_off.xml new file mode 100644 index 000000000000..a8102519361b --- /dev/null +++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp_off.xml @@ -0,0 +1,26 @@ +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M19.5,19.5l-6,-6L12,12L7.5,7.5L6,6L2.81,2.81L1.75,3.87l2.17,2.17C2.83,6.2 2,7.12 2,8.25v10.5C2,19.99 3.01,21 4.25,21h14.63l1.25,1.25l1.06,-1.06l-0.44,-0.44L19.5,19.5zM4.25,19.5c-0.41,0 -0.75,-0.34 -0.75,-0.75V8.25c0,-0.41 0.34,-0.75 0.75,-0.75h1.13l5.27,5.27c-0.09,0.19 -0.15,0.42 -0.15,0.73c0,1.59 1.43,1.5 1.5,1.5c0.02,0 0.38,0.02 0.74,-0.14l4.64,4.64H4.25z"/> + <path + android:fillColor="#FF000000" + android:pathData="M9.62,7.5h10.13c0.41,0 0.75,0.34 0.75,0.75v10.13l1.28,1.28c0.13,-0.28 0.22,-0.58 0.22,-0.91V8.25C22,7.01 20.99,6 19.75,6H16c0,0 0,0 0,0c0,-2.05 -0.95,-4 -4,-4C9.01,2 8.04,3.9 8.01,5.89L9.62,7.5zM12,3.5c0.54,-0.01 2.5,-0.11 2.5,2.5c0,0 0,0 0,0h-5c0,0 0,0 0,0C9.5,3.39 11.45,3.48 12,3.5z"/> +</vector> diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_screenshot.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_screenshot.xml new file mode 100644 index 000000000000..e8608a598fbf --- /dev/null +++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_screenshot.xml @@ -0,0 +1,29 @@ +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M16.75,1h-9.5C6.01,1 5,2.01 5,3.25v17.5C5,21.99 6.01,23 7.25,23h9.5c1.24,0 2.25,-1.01 2.25,-2.25V3.25C19,2.01 17.99,1 16.75,1zM7.25,2.5h9.5c0.41,0 0.75,0.34 0.75,0.75v1h-11v-1C6.5,2.84 6.84,2.5 7.25,2.5zM17.5,5.75v12.5h-11V5.75H17.5zM16.75,21.5h-9.5c-0.41,0 -0.75,-0.34 -0.75,-0.75v-1h11v1C17.5,21.16 17.16,21.5 16.75,21.5z"/> + <path + android:fillColor="#FF000000" + android:pathData="M9.5,11V8.5H12V7H8.75C8.34,7 8,7.34 8,7.75V11H9.5z"/> + <path + android:fillColor="#FF000000" + android:pathData="M12,17h3.25c0.41,0 0.75,-0.34 0.75,-0.75V13h-1.5v2.5H12V17z"/> +</vector> diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_select.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_select.xml new file mode 100644 index 000000000000..4e265fd9c5d5 --- /dev/null +++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_select.xml @@ -0,0 +1,32 @@ +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M11.25,1h1.5v3h-1.5z"/> + <path + android:fillColor="#FF000000" + android:pathData="M15.5983,5.3402l2.1213,-2.1213l1.0606,1.0606l-2.1213,2.1213z"/> + <path + android:fillColor="#FF000000" + android:pathData="M5.2187,4.2803l1.0606,-1.0606l2.1213,2.1213l-1.0606,1.0606z"/> + <path + android:fillColor="#FF000000" + android:pathData="M15.5,12.5l-1.25,0V8.12C14.25,6.95 13.3,6 12.12,6S10,6.95 10,8.12v7.9L8.03,15.5c-0.39,-0.1 -1.23,-0.36 -2.56,0.97c-0.29,0.29 -0.29,0.75 -0.01,1.05l3.79,3.98c0,0 0,0 0,0.01c1.37,1.41 3.28,1.51 4.04,1.49l2.2,0c2.12,0.06 5.25,-1.01 5.25,-5.25C20.75,13.19 17.23,12.46 15.5,12.5zM15.5,21.5l-2.25,0c-0.44,0.01 -1.93,-0.02 -2.92,-1.03l-3.27,-3.43c0.17,-0.1 0.38,-0.13 0.58,-0.08l2.91,0.78c0.47,0.12 0.94,-0.23 0.94,-0.72V8.12c0,-0.34 0.28,-0.62 0.62,-0.62s0.62,0.28 0.62,0.62v5.12c0,0.41 0.33,0.75 0.75,0.75l2.05,0c1.26,-0.03 3.7,0.37 3.7,3.75C19.25,21.14 16.78,21.53 15.5,21.5z"/> +</vector> diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_share.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_share.xml new file mode 100644 index 000000000000..726d1aa5e1c2 --- /dev/null +++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_share.xml @@ -0,0 +1,39 @@ +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M17.88,3.5l0.06,0l0.04,0H18l0.04,0l0.02,0l0.06,0c1.38,0 1.38,1.01 1.38,1.5s0,1.5 -1.38,1.5l-0.06,0l-0.04,0H18l-0.04,0l-0.02,0l-0.06,0C16.5,6.5 16.5,5.49 16.5,5S16.5,3.5 17.88,3.5M17.88,2C17.33,2 15,2.15 15,5c0,2.85 2.31,3 2.88,3c0.06,0 0.11,0 0.12,0c0.01,0 0.05,0 0.12,0C18.67,8 21,7.85 21,5c0,-2.85 -2.31,-3 -2.88,-3C18.06,2 18.01,2 18,2C17.99,2 17.95,2 17.88,2L17.88,2z"/> + <path + android:fillColor="#FF000000" + android:pathData="M17.88,17.5l0.06,0l0.04,0H18l0.04,0l0.02,0l0.06,0c1.38,0 1.38,1.01 1.38,1.5s0,1.5 -1.38,1.5l-0.06,0l-0.04,0H18l-0.04,0l-0.02,0l-0.06,0c-1.38,0 -1.38,-1.01 -1.38,-1.5S16.5,17.5 17.88,17.5M17.88,16C17.33,16 15,16.15 15,19c0,2.85 2.31,3 2.88,3c0.06,0 0.11,0 0.12,0c0.01,0 0.05,0 0.12,0c0.56,0 2.88,-0.15 2.88,-3c0,-2.85 -2.31,-3 -2.88,-3c-0.06,0 -0.11,0 -0.12,0C17.99,16 17.95,16 17.88,16L17.88,16z"/> + <path + android:fillColor="#FF000000" + android:pathData="M5.88,10.5l0.06,0l0.04,0H6l0.04,0l0.02,0l0.06,0c1.38,0 1.38,1.01 1.38,1.5s0,1.5 -1.38,1.5l-0.06,0l-0.04,0H6l-0.04,0l-0.02,0l-0.06,0C4.5,13.5 4.5,12.49 4.5,12S4.5,10.5 5.88,10.5M5.88,9C5.33,9 3,9.15 3,12c0,2.85 2.31,3 2.88,3c0.06,0 0.11,0 0.12,0c0.01,0 0.05,0 0.12,0C6.67,15 9,14.85 9,12c0,-2.85 -2.31,-3 -2.88,-3C6.06,9 6.01,9 6,9C5.99,9 5.95,9 5.88,9L5.88,9z"/> + <path + android:pathData="M16.01,6.16L8,10.83" + android:strokeWidth="1.5" + android:fillColor="#00000000" + android:strokeColor="#000000"/> + <path + android:pathData="M16.06,17.87L8.19,13.28" + android:strokeWidth="1.5" + android:fillColor="#00000000" + android:strokeColor="#000000"/> +</vector> diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml index 7139313a9ef9..0dfaf8188f8d 100644 --- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml +++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml @@ -1,27 +1,23 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2019 The Android Open Source Project +<!-- Copyright (C) 2020 The Android Open Source Project - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + 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 + 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. + 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:tint="?android:attr/textColorHint" - android:viewportHeight="24" android:viewportWidth="24" - android:width="24dp" > - <path android:pathData="M 10 4 H 14 V 6 H 10 V 4 Z" /> - <path - android:fillColor="@android:color/white" - android:pathData="M20,6h-4V4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H4C2.9,6,2,6.9,2,8l0,11c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8 C22,6.9,21.1,6,20,6z M12,15c-0.8,0-1.5-0.7-1.5-1.5S11.2,12,12,12s1.5,0.7,1.5,1.5S12.8,15,12,15z M14,6h-4V4h4V6z" /> -</vector>
\ No newline at end of file + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M19,6h-3c0,-2.21 -1.79,-4 -4,-4S8,3.79 8,6H5C3.34,6 2,7.34 2,9v9c0,1.66 1.34,3 3,3h14c1.66,0 3,-1.34 3,-3V9C22,7.34 20.66,6 19,6zM12,15c-0.83,0 -1.5,-0.67 -1.5,-1.5S11.17,12 12,12s1.5,0.67 1.5,1.5S12.83,15 12,15zM10,6c0,-1.1 0.9,-2 2,-2s2,0.9 2,2H10z"/> +</vector> diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp_off.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp_off.xml new file mode 100644 index 000000000000..b3f353a16943 --- /dev/null +++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp_off.xml @@ -0,0 +1,26 @@ +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M21.81,18.98C21.92,18.67 22,18.35 22,18V9c0,-1.66 -1.34,-3 -3,-3h-3c0,-2.21 -1.79,-4 -4,-4c-1.95,0 -3.57,1.4 -3.92,3.24L21.81,18.98zM12,4c1.1,0 2,0.9 2,2h-4C10,4.9 10.9,4 12,4z"/> + <path + android:fillColor="#FF000000" + android:pathData="M20.56,20.55l-17,-17c0,0 0,0 0,0L3.45,3.44c-0.39,-0.39 -1.02,-0.39 -1.41,0s-0.39,1.02 0,1.41l1.53,1.53C2.64,6.89 2,7.87 2,9v9c0,1.66 1.34,3 3,3h13.18l0.96,0.96c0.2,0.2 0.45,0.29 0.71,0.29s0.51,-0.1 0.71,-0.29C20.94,21.57 20.94,20.94 20.56,20.55C20.56,20.55 20.56,20.55 20.56,20.55zM12,15c-0.83,0 -1.5,-0.67 -1.5,-1.5c0,-0.06 0.01,-0.11 0.02,-0.16l1.65,1.65C12.11,14.99 12.06,15 12,15z"/> +</vector> diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_screenshot.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_screenshot.xml new file mode 100644 index 000000000000..1d291c93fb4d --- /dev/null +++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_screenshot.xml @@ -0,0 +1,29 @@ +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M8.75,11c0.41,0 0.75,-0.34 0.75,-0.75V8.5h1.75C11.66,8.5 12,8.16 12,7.75C12,7.34 11.66,7 11.25,7H9C8.45,7 8,7.45 8,8v2.25C8,10.66 8.34,11 8.75,11z"/> + <path + android:fillColor="#FF000000" + android:pathData="M12.75,17H15c0.55,0 1,-0.45 1,-1v-2.25c0,-0.41 -0.34,-0.75 -0.75,-0.75s-0.75,0.34 -0.75,0.75v1.75h-1.75c-0.41,0 -0.75,0.34 -0.75,0.75C12,16.66 12.34,17 12.75,17z"/> + <path + android:fillColor="#FF000000" + android:pathData="M16,1H8C6.34,1 5,2.34 5,4v16c0,1.65 1.35,3 3,3h8c1.65,0 3,-1.35 3,-3V4C19,2.34 17.66,1 16,1zM17,18H7V6h10V18z"/> +</vector> diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_select.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_select.xml new file mode 100644 index 000000000000..df4525d48777 --- /dev/null +++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_select.xml @@ -0,0 +1,32 @@ +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M17.59,5.83l0.71,-0.71c0.39,-0.39 0.39,-1.02 0,-1.41l0,0c-0.39,-0.39 -1.02,-0.39 -1.41,0l-0.71,0.71c-0.39,0.39 -0.39,1.02 0,1.41C16.56,6.21 17.2,6.21 17.59,5.83z"/> + <path + android:fillColor="#FF000000" + android:pathData="M12,4c0.55,0 1,-0.45 1,-1V2c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v1C11,3.55 11.45,4 12,4z"/> + <path + android:fillColor="#FF000000" + android:pathData="M6.42,5.83c0.39,0.39 1.02,0.39 1.41,0c0.39,-0.39 0.39,-1.02 0,-1.41L7.12,3.71c-0.39,-0.39 -1.02,-0.39 -1.41,0l0,0c-0.39,0.39 -0.39,1.02 0,1.41L6.42,5.83z"/> + <path + android:fillColor="#FF000000" + android:pathData="M17.95,14.43l-3.23,-1.61c-0.42,-0.21 -0.88,-0.32 -1.34,-0.32H13v-5C13,6.67 12.33,6 11.5,6C10.67,6 10,6.67 10,7.5v9.12c0,0.32 -0.29,0.55 -0.6,0.49l-2.84,-0.6c-0.37,-0.08 -0.76,0.04 -1.03,0.31c-0.43,0.44 -0.43,1.14 0.01,1.58l3.71,3.71C9.81,22.68 10.58,23 11.37,23h4.82c1.49,0 2.76,-1.1 2.97,-2.58l0.41,-2.89C19.76,16.26 19.1,15.01 17.95,14.43z"/> +</vector> diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_share.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_share.xml new file mode 100644 index 000000000000..89ee5274e48f --- /dev/null +++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_share.xml @@ -0,0 +1,39 @@ +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M18,5L6,12" + android:strokeWidth="2" + android:fillColor="#00000000" + android:strokeColor="#000000"/> + <path + android:pathData="M18,19L6,12" + android:strokeWidth="2" + android:fillColor="#00000000" + android:strokeColor="#000000"/> + <path + android:fillColor="#FF000000" + android:pathData="M18,5m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"/> + <path + android:fillColor="#FF000000" + android:pathData="M18,19m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"/> + <path + android:fillColor="#FF000000" + android:pathData="M6,12m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"/> +</vector> diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml index 38f515fdb22d..be31fb9171bf 100644 --- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml +++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml @@ -1,29 +1,26 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2019 The Android Open Source Project +<!-- Copyright (C) 2020 The Android Open Source Project - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + 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 + 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. + 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:tint="?android:attr/textColorHint" - android:viewportHeight="24" android:viewportWidth="24" - android:width="24dp" > - <path - android:fillColor="@android:color/white" - android:pathData="M20,6h-4V4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H4C2.9,6,2,6.9,2,8v11c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8 C22,6.9,21.1,6,20,6z M9.5,4c0-0.3,0.2-0.5,0.5-0.5h4c0.3,0,0.5,0.2,0.5,0.5v2h-5V4z M20.5,19c0,0.3-0.2,0.5-0.5,0.5H4 c-0.3,0-0.5-0.2-0.5-0.5V8c0-0.3,0.2-0.5,0.5-0.5h16c0.3,0,0.5,0.2,0.5,0.5V19z" /> - <path - android:fillColor="@android:color/white" - android:pathData="M 12 12.3 C 12.6627416998 12.3 13.2 12.8372583002 13.2 13.5 C 13.2 14.1627416998 12.6627416998 14.7 12 14.7 C 11.3372583002 14.7 10.8 14.1627416998 10.8 13.5 C 10.8 12.8372583002 11.3372583002 12.3 12 12.3 Z" /> -</vector>
\ No newline at end of file + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M20.59,6H16V3.41L14.59,2H9.41L8,3.41V6H3.41L2,7.41v12.17L3.41,21h17.17L22,19.59V7.41L20.59,6zM9.5,3.5h5V6h-5V3.5zM20.5,19.5h-17v-12h17V19.5z"/> + <path + android:fillColor="#FF000000" + android:pathData="M12,13.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/> +</vector> diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp_off.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp_off.xml new file mode 100644 index 000000000000..8d298f7cbc97 --- /dev/null +++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp_off.xml @@ -0,0 +1,26 @@ +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M19.5,19.5l-6,-6L12,12L7.5,7.5L6,6L2.81,2.81L1.75,3.87L3.88,6H3.41L2,7.41v12.17L3.41,21h15.46l1.25,1.25l1.06,-1.06l-0.4,-0.4L19.5,19.5zM3.5,19.5v-12h1.88l5.3,5.3c-0.11,0.21 -0.18,0.44 -0.18,0.7c0,0.83 0.67,1.5 1.5,1.5c0.25,0 0.49,-0.07 0.7,-0.18l4.68,4.68H3.5z"/> + <path + android:fillColor="#FF000000" + android:pathData="M9.62,7.5H20.5v10.88l1.35,1.35L22,19.59V7.41L20.59,6H16V3.41L14.59,2H9.41L8,3.41v2.46L9.62,7.5zM9.5,3.5h5V6h-5V3.5z"/> +</vector> diff --git a/packages/Tethering/res/values-mcc311-mnc490/strings.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_screenshot.xml index 618df90c7105..ed90b85c8b87 100644 --- a/packages/Tethering/res/values-mcc311-mnc490/strings.xml +++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_screenshot.xml @@ -1,4 +1,3 @@ -<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2020 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,10 +12,18 @@ See the License for the specific language governing permissions and limitations under the License. --> -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- String for tethered notification title with client number info. --> - <plurals name="tethered_notification_title_with_client_number"> - <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item> - <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item> - </plurals> -</resources>
\ No newline at end of file +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M17.59,1H6.41L5,2.41v19.17L6.41,23h11.17L19,21.59V2.41L17.59,1zM17.5,2.5v1.75h-11V2.5H17.5zM17.5,5.75v12.5h-11V5.75H17.5zM6.5,21.5v-1.75h11v1.75H6.5z"/> + <path + android:fillColor="#FF000000" + android:pathData="M9.5,11l0,-2.5l2.5,0l0,-1.5l-4,0l0,4z"/> + <path + android:fillColor="#FF000000" + android:pathData="M12,17l4,0l0,-4l-1.5,0l0,2.5l-2.5,0z"/> +</vector> diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_select.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_select.xml new file mode 100644 index 000000000000..b699a4444d76 --- /dev/null +++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_select.xml @@ -0,0 +1,32 @@ +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M16.19,12.5h-1.94V8.12C14.25,6.95 13.3,6 12.12,6S10,6.95 10,8.12v7.9l-3.22,-0.86l-1.82,1.82L10.68,23h8.6l1.57,-7.96L16.19,12.5zM18.04,21.5h-6.72l-4.27,-4.49l0.18,-0.18l4.28,1.14V8.12c0,-0.34 0.28,-0.62 0.62,-0.62s0.62,0.28 0.62,0.62V14h3.06l3.35,1.83L18.04,21.5z"/> + <path + android:fillColor="#FF000000" + android:pathData="M11.25,1h1.5v3h-1.5z"/> + <path + android:fillColor="#FF000000" + android:pathData="M15.5983,5.3402l2.1213,-2.1213l1.0606,1.0606l-2.1213,2.1213z"/> + <path + android:fillColor="#FF000000" + android:pathData="M5.2187,4.2803l1.0606,-1.0606l2.1213,2.1213l-1.0606,1.0606z"/> +</vector> diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_share.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_share.xml new file mode 100644 index 000000000000..36dd3baa8994 --- /dev/null +++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_share.xml @@ -0,0 +1,39 @@ +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M18,3.5c0.83,0 1.5,0.67 1.5,1.5S18.83,6.5 18,6.5S16.5,5.83 16.5,5S17.17,3.5 18,3.5M18,2c-1.66,0 -3,1.34 -3,3s1.34,3 3,3s3,-1.34 3,-3S19.66,2 18,2L18,2z"/> + <path + android:fillColor="#FF000000" + android:pathData="M18,17.5c0.83,0 1.5,0.67 1.5,1.5s-0.67,1.5 -1.5,1.5s-1.5,-0.67 -1.5,-1.5S17.17,17.5 18,17.5M18,16c-1.66,0 -3,1.34 -3,3s1.34,3 3,3s3,-1.34 3,-3S19.66,16 18,16L18,16z"/> + <path + android:fillColor="#FF000000" + android:pathData="M6,10.5c0.83,0 1.5,0.67 1.5,1.5S6.83,13.5 6,13.5S4.5,12.83 4.5,12S5.17,10.5 6,10.5M6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3s3,-1.34 3,-3S7.66,9 6,9L6,9z"/> + <path + android:pathData="M16.01,6.16L8,10.83" + android:strokeWidth="1.5" + android:fillColor="#00000000" + android:strokeColor="#000000"/> + <path + android:pathData="M16.06,17.87L8.19,13.28" + android:strokeWidth="1.5" + android:fillColor="#00000000" + android:strokeColor="#000000"/> +</vector> diff --git a/services/Android.bp b/services/Android.bp index 730b9a5dc3e3..6d637bedeef7 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -112,7 +112,6 @@ droidstubs { name: "services-stubs.sources", srcs: [":services-all-sources"], installable: false, - api_tag_name: "SYSTEM_SERVER", args: " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.SYSTEM_SERVER\\)" + " --hide-annotation android.annotation.Hide" + " --hide InternalClasses" + // com.android.* classes are okay in this interface diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java index 132b6927badd..da9bdf3262d5 100644 --- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java @@ -1023,8 +1023,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ try { mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { final ScreenshotGraphicBuffer screenshotBuffer = LocalServices - .getService(DisplayManagerInternal.class) - .screenshotWithoutSecureLayer(displayId); + .getService(DisplayManagerInternal.class).userScreenshot(displayId); if (screenshotBuffer != null) { sendScreenshotSuccess(screenshotBuffer, callback); } else { diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index ce651100699f..4009cafd04fb 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -603,8 +603,7 @@ class AlarmManagerService extends SystemService { } pw.print(KEY_APP_STANDBY_RESTRICTED_QUOTA); pw.print("="); - TimeUtils.formatDuration(APP_STANDBY_RESTRICTED_QUOTA, pw); - pw.println(); + pw.println(APP_STANDBY_RESTRICTED_QUOTA); pw.print(KEY_APP_STANDBY_RESTRICTED_WINDOW); pw.print("="); TimeUtils.formatDuration(APP_STANDBY_RESTRICTED_WINDOW, pw); diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 2bbf27849005..97a5cfe6006d 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -1146,7 +1146,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { && registrationLimit >= 1 && numRecordsForPid >= registrationLimit) { String errorMsg = "Pid " + callingPid + " has exceeded the number of permissible" - + "registered listeners. Ignoring request to add."; + + " registered listeners. Ignoring request to add."; loge(errorMsg); if (mConfigurationProvider .isRegistrationLimitEnabledInPlatformCompat(callingUid)) { @@ -1157,7 +1157,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { // Log the warning independently of the dynamically set limit -- apps shouldn't be // doing this regardless of whether we're throwing them an exception for it. Rlog.w(TAG, "Pid " + callingPid + " has exceeded half the number of permissible" - + "registered listeners. Now at " + numRecordsForPid); + + " registered listeners. Now at " + numRecordsForPid); } r = new Record(); diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index 58c388ed08c6..b09d74180c4b 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -122,7 +122,6 @@ final class UiModeManagerService extends SystemService { private boolean mVrHeadset; private boolean mComputedNightMode; private int mCarModeEnableFlags; - private boolean mSetupWizardComplete; // flag set by resource, whether to enable Car dock launch when starting car mode. private boolean mEnableCarDockLaunch = true; @@ -164,12 +163,6 @@ final class UiModeManagerService extends SystemService { mConfiguration.setToDefaults(); } - @VisibleForTesting - protected UiModeManagerService(Context context, boolean setupWizardComplete) { - this(context); - mSetupWizardComplete = setupWizardComplete; - } - private static Intent buildHomeIntent(String category) { Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(category); @@ -283,25 +276,6 @@ final class UiModeManagerService extends SystemService { } }; - private final ContentObserver mSetupWizardObserver = new ContentObserver(mHandler) { - @Override - public void onChange(boolean selfChange, Uri uri) { - synchronized (mLock) { - // setup wizard is done now so we can unblock - if (setupWizardCompleteForCurrentUser() && !selfChange) { - mSetupWizardComplete = true; - getContext().getContentResolver() - .unregisterContentObserver(mSetupWizardObserver); - // update night mode - Context context = getContext(); - updateNightModeFromSettingsLocked(context, context.getResources(), - UserHandle.getCallingUserId()); - updateLocked(0, 0); - } - } - } - }; - private final ContentObserver mDarkThemeObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange, Uri uri) { @@ -319,13 +293,6 @@ final class UiModeManagerService extends SystemService { } @Override - public void onSwitchUser(int userHandle) { - super.onSwitchUser(userHandle); - getContext().getContentResolver().unregisterContentObserver(mSetupWizardObserver); - verifySetupWizardCompleted(); - } - - @Override public void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { synchronized (mLock) { @@ -351,6 +318,8 @@ final class UiModeManagerService extends SystemService { context.registerReceiver(mBatteryReceiver, batteryFilter); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_SWITCHED); + context.registerReceiver(mSettingsRestored, + new IntentFilter(Intent.ACTION_SETTING_RESTORED)); context.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler); updateConfigurationLocked(); applyConfigurationExternallyLocked(); @@ -361,9 +330,6 @@ final class UiModeManagerService extends SystemService { @Override public void onStart() { final Context context = getContext(); - // If setup isn't complete for this user listen for completion so we can unblock - // being able to send a night mode configuration change event - verifySetupWizardCompleted(); final Resources res = context.getResources(); mDefaultUiModeType = res.getInteger( @@ -438,20 +404,6 @@ final class UiModeManagerService extends SystemService { return mConfiguration; } - // Records whether setup wizard has happened or not and adds an observer for this user if not. - private void verifySetupWizardCompleted() { - final Context context = getContext(); - final int userId = UserHandle.getCallingUserId(); - if (!setupWizardCompleteForCurrentUser()) { - mSetupWizardComplete = false; - context.getContentResolver().registerContentObserver( - Secure.getUriFor( - Secure.USER_SETUP_COMPLETE), false, mSetupWizardObserver, userId); - } else { - mSetupWizardComplete = true; - } - } - private boolean setupWizardCompleteForCurrentUser() { return Secure.getIntForUser(getContext().getContentResolver(), Secure.USER_SETUP_COMPLETE, 0, UserHandle.getCallingUserId()) == 1; @@ -480,28 +432,20 @@ final class UiModeManagerService extends SystemService { final int defaultNightMode = res.getInteger( com.android.internal.R.integer.config_defaultNightMode); int oldNightMode = mNightMode; - if (mSetupWizardComplete) { - mNightMode = Secure.getIntForUser(context.getContentResolver(), - Secure.UI_NIGHT_MODE, defaultNightMode, userId); - mOverrideNightModeOn = Secure.getIntForUser(context.getContentResolver(), - Secure.UI_NIGHT_MODE_OVERRIDE_ON, 0, userId) != 0; - mOverrideNightModeOff = Secure.getIntForUser(context.getContentResolver(), - Secure.UI_NIGHT_MODE_OVERRIDE_OFF, 0, userId) != 0; - mCustomAutoNightModeStartMilliseconds = LocalTime.ofNanoOfDay( - Secure.getLongForUser(context.getContentResolver(), - Secure.DARK_THEME_CUSTOM_START_TIME, - DEFAULT_CUSTOM_NIGHT_START_TIME.toNanoOfDay() / 1000L, userId) * 1000); - mCustomAutoNightModeEndMilliseconds = LocalTime.ofNanoOfDay( - Secure.getLongForUser(context.getContentResolver(), - Secure.DARK_THEME_CUSTOM_END_TIME, - DEFAULT_CUSTOM_NIGHT_END_TIME.toNanoOfDay() / 1000L, userId) * 1000); - } else { - mNightMode = defaultNightMode; - mCustomAutoNightModeEndMilliseconds = DEFAULT_CUSTOM_NIGHT_END_TIME; - mCustomAutoNightModeStartMilliseconds = DEFAULT_CUSTOM_NIGHT_START_TIME; - mOverrideNightModeOn = false; - mOverrideNightModeOff = false; - } + mNightMode = Secure.getIntForUser(context.getContentResolver(), + Secure.UI_NIGHT_MODE, defaultNightMode, userId); + mOverrideNightModeOn = Secure.getIntForUser(context.getContentResolver(), + Secure.UI_NIGHT_MODE_OVERRIDE_ON, 0, userId) != 0; + mOverrideNightModeOff = Secure.getIntForUser(context.getContentResolver(), + Secure.UI_NIGHT_MODE_OVERRIDE_OFF, 0, userId) != 0; + mCustomAutoNightModeStartMilliseconds = LocalTime.ofNanoOfDay( + Secure.getLongForUser(context.getContentResolver(), + Secure.DARK_THEME_CUSTOM_START_TIME, + DEFAULT_CUSTOM_NIGHT_START_TIME.toNanoOfDay() / 1000L, userId) * 1000); + mCustomAutoNightModeEndMilliseconds = LocalTime.ofNanoOfDay( + Secure.getLongForUser(context.getContentResolver(), + Secure.DARK_THEME_CUSTOM_END_TIME, + DEFAULT_CUSTOM_NIGHT_END_TIME.toNanoOfDay() / 1000L, userId) * 1000); return oldNightMode != mNightMode; } @@ -644,10 +588,6 @@ final class UiModeManagerService extends SystemService { Slog.e(TAG, "Night mode locked, requires MODIFY_DAY_NIGHT_MODE permission"); return; } - if (!mSetupWizardComplete) { - Slog.d(TAG, "Night mode cannot be changed before setup wizard completes."); - return; - } switch (mode) { case UiModeManager.MODE_NIGHT_NO: case UiModeManager.MODE_NIGHT_YES: diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index debc2a116934..27c3ff1b4c09 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -46,6 +46,7 @@ import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; import android.content.BroadcastReceiver; +import android.content.ClipData; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -4757,6 +4758,11 @@ public class AccountManagerService * supplied entries in the system Settings app. */ protected boolean checkKeyIntent(int authUid, Intent intent) { + // Explicitly set an empty ClipData to ensure that we don't offer to + // promote any Uris contained inside for granting purposes + if (intent.getClipData() == null) { + intent.setClipData(ClipData.newPlainText(null, null)); + } intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 21760cdf02eb..419389f7abef 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -119,7 +119,6 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Comparator; -import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.function.Predicate; @@ -1753,8 +1752,8 @@ public final class ActiveServices { private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { boolean anyForeground = false; int fgServiceTypes = 0; - for (int i = proc.services.size() - 1; i >= 0; i--) { - ServiceRecord sr = proc.services.valueAt(i); + for (int i = proc.numberOfRunningServices() - 1; i >= 0; i--) { + ServiceRecord sr = proc.getRunningServiceAt(i); if (sr.isForeground || sr.fgRequired) { anyForeground = true; fgServiceTypes |= sr.foregroundServiceType; @@ -1765,8 +1764,8 @@ public final class ActiveServices { private void updateWhitelistManagerLocked(ProcessRecord proc) { proc.whitelistManager = false; - for (int i=proc.services.size()-1; i>=0; i--) { - ServiceRecord sr = proc.services.valueAt(i); + for (int i = proc.numberOfRunningServices() - 1; i >= 0; i--) { + ServiceRecord sr = proc.getRunningServiceAt(i); if (sr.whitelistManager) { proc.whitelistManager = true; break; @@ -1802,8 +1801,8 @@ public final class ActiveServices { } boolean anyClientActivities = false; - for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) { - ServiceRecord sr = proc.services.valueAt(i); + for (int i = proc.numberOfRunningServices() - 1; i >= 0 && !anyClientActivities; i--) { + ServiceRecord sr = proc.getRunningServiceAt(i); ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = sr.getConnections(); for (int conni = connections.size() - 1; conni >= 0 && !anyClientActivities; conni--) { ArrayList<ConnectionRecord> clist = connections.valueAt(conni); @@ -2995,7 +2994,7 @@ public final class ActiveServices { r.setProcess(app); r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); - final boolean newService = app.services.add(r); + final boolean newService = app.startService(r); bumpServiceExecutingLocked(r, execInFg, "create"); mAm.updateLruProcessLocked(app, false, null); updateServiceForegroundLocked(r.app, /* oomAdj= */ false); @@ -3036,7 +3035,7 @@ public final class ActiveServices { // Cleanup. if (newService) { - app.services.remove(r); + app.stopService(r); r.setProcess(null); } @@ -3362,7 +3361,7 @@ public final class ActiveServices { synchronized (r.stats.getBatteryStats()) { r.stats.stopLaunchedLocked(); } - r.app.services.remove(r); + r.app.stopService(r); r.app.updateBoundClientUids(); if (r.whitelistManager) { updateWhitelistManagerLocked(r.app); @@ -3652,7 +3651,7 @@ public final class ActiveServices { } if (finishing) { if (r.app != null && !r.app.isPersistent()) { - r.app.services.remove(r); + r.app.stopService(r); r.app.updateBoundClientUids(); if (r.whitelistManager) { updateWhitelistManagerLocked(r.app); @@ -3748,7 +3747,7 @@ public final class ActiveServices { didSomething = true; Slog.i(TAG, " Force stopping service " + service); if (service.app != null && !service.app.isPersistent()) { - service.app.services.remove(service); + service.app.stopService(service); service.app.updateBoundClientUids(); if (service.whitelistManager) { updateWhitelistManagerLocked(service.app); @@ -3861,24 +3860,22 @@ public final class ActiveServices { if (false) { // XXX we are letting the client link to the service for // death notifications. - if (app.services.size() > 0) { - Iterator<ServiceRecord> it = app.services.iterator(); - while (it.hasNext()) { - ServiceRecord r = it.next(); - ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); - for (int conni=connections.size()-1; conni>=0; conni--) { - ArrayList<ConnectionRecord> cl = connections.valueAt(conni); - for (int i=0; i<cl.size(); i++) { - ConnectionRecord c = cl.get(i); - if (c.binding.client != app) { - try { - //c.conn.connected(r.className, null); - } catch (Exception e) { - // todo: this should be asynchronous! - Slog.w(TAG, "Exception thrown disconnected servce " - + r.shortInstanceName - + " from app " + app.processName, e); - } + int numberOfRunningServices = app.numberOfRunningServices(); + for (int sIndex = 0; sIndex < numberOfRunningServices; sIndex++) { + ServiceRecord r = app.getRunningServiceAt(sIndex); + ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); + for (int conni = connections.size() - 1; conni >= 0; conni--) { + ArrayList<ConnectionRecord> cl = connections.valueAt(conni); + for (int i = 0; i < cl.size(); i++) { + ConnectionRecord c = cl.get(i); + if (c.binding.client != app) { + try { + //c.conn.connected(r.className, null); + } catch (Exception e) { + // todo: this should be asynchronous! + Slog.w(TAG, "Exception thrown disconnected servce " + + r.shortInstanceName + + " from app " + app.processName, e); } } } @@ -3897,13 +3894,13 @@ public final class ActiveServices { app.whitelistManager = false; // Clear app state from services. - for (int i = app.services.size() - 1; i >= 0; i--) { - ServiceRecord sr = app.services.valueAt(i); + for (int i = app.numberOfRunningServices() - 1; i >= 0; i--) { + ServiceRecord sr = app.getRunningServiceAt(i); synchronized (sr.stats.getBatteryStats()) { sr.stats.stopLaunchedLocked(); } if (sr.app != app && sr.app != null && !sr.app.isPersistent()) { - sr.app.services.remove(sr); + sr.app.stopService(sr); sr.app.updateBoundClientUids(); } sr.setProcess(null); @@ -3962,13 +3959,13 @@ public final class ActiveServices { ServiceMap smap = getServiceMapLocked(app.userId); // Now do remaining service cleanup. - for (int i=app.services.size()-1; i>=0; i--) { - ServiceRecord sr = app.services.valueAt(i); + for (int i = app.numberOfRunningServices() - 1; i >= 0; i--) { + ServiceRecord sr = app.getRunningServiceAt(i); // Unless the process is persistent, this process record is going away, // so make sure the service is cleaned out of it. if (!app.isPersistent()) { - app.services.removeAt(i); + app.stopService(sr); app.updateBoundClientUids(); } @@ -4018,7 +4015,7 @@ public final class ActiveServices { } if (!allowRestart) { - app.services.clear(); + app.stopAllServices(); app.clearBoundClientUids(); // Make sure there are no more restarting services for this process. @@ -4920,8 +4917,8 @@ public final class ActiveServices { if (pr.uid != uid) { continue; } - for (int j = pr.services.size() - 1; j >= 0; j--) { - ServiceRecord r = pr.services.valueAt(j); + for (int j = pr.numberOfRunningServices() - 1; j >= 0; j--) { + ServiceRecord r = pr.getRunningServiceAt(j); if (!r.isForeground) { continue; } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 3fdf541566a5..5d7590d7a458 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -18172,7 +18172,7 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i = mProcessList.mRemovedProcesses.size() - 1; i >= 0; i--) { final ProcessRecord app = mProcessList.mRemovedProcesses.get(i); if (!app.hasActivitiesOrRecentTasks() - && app.curReceivers.isEmpty() && app.services.size() == 0) { + && app.curReceivers.isEmpty() && app.numberOfRunningServices() == 0) { Slog.i( TAG, "Exiting empty application process " + app.toShortString() + " (" @@ -20045,8 +20045,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (uid == mTargetUid && isTargetOp(code)) { final long identity = Binder.clearCallingIdentity(); try { - return mAppOpsService.noteProxyOperation(code, Process.SHELL_UID, - "com.android.shell", null, uid, packageName, featureId, + return superImpl.apply(code, Process.SHELL_UID, "com.android.shell", featureId, shouldCollectAsyncNotedOp, message); } finally { Binder.restoreCallingIdentity(identity); diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index b1fc0296518b..50d2cab0af81 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -702,10 +702,10 @@ class AppErrors { } // Bump up the crash count of any services currently running in the proc. - for (int i = app.services.size() - 1; i >= 0; i--) { + for (int i = app.numberOfRunningServices() - 1; i >= 0; i--) { // Any services running in the application need to be placed // back in the pending list. - ServiceRecord sr = app.services.valueAt(i); + ServiceRecord sr = app.getRunningServiceAt(i); // If the service was restarted a while ago, then reset crash count, else increment it. if (now > sr.restartTime + ProcessList.MIN_CRASH_INTERVAL) { sr.crashCount = 1; diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index dbad562c0271..b647818e3f7a 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -1013,9 +1013,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub @Override public void noteNetworkInterfaceType(String iface, int networkType) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteNetworkInterfaceTypeLocked(iface, networkType); - } + mStats.noteNetworkInterfaceType(iface, networkType); } @Override diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 2d6ef81faf1c..ad858533c430 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -837,7 +837,8 @@ public final class OomAdjuster { break; } - if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) { + if (app.isolated && app.numberOfRunningServices() <= 0 + && app.isolatedEntryPoint == null) { // If this is an isolated process, there are no services // running in it, and it's not a special process with a // custom entry point, then the process is no longer @@ -1446,12 +1447,12 @@ public final class OomAdjuster { } int capabilityFromFGS = 0; // capability from foreground service. - for (int is = app.services.size() - 1; + for (int is = app.numberOfRunningServices() - 1; is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > PROCESS_STATE_TOP); is--) { - ServiceRecord s = app.services.valueAt(is); + ServiceRecord s = app.getRunningServiceAt(is); if (s.startRequested) { app.hasStartedServices = true; if (procState > PROCESS_STATE_SERVICE) { diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index e28464a27dc4..c9ee47278796 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -2181,6 +2181,17 @@ public final class ProcessList { return result; } + private boolean needsStorageDataIsolation(StorageManagerInternal storageManagerInternal, + ProcessRecord app) { + return mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid) + && !storageManagerInternal.isExternalStorageService(app.uid) + // Special mounting mode doesn't need to have data isolation as they won't + // access /mnt/user anyway. + && app.mountMode != Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE + && app.mountMode != Zygote.MOUNT_EXTERNAL_PASS_THROUGH + && app.mountMode != Zygote.MOUNT_EXTERNAL_INSTALLER; + } + private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint, ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal, String seInfo, String requiredAbi, String instructionSet, @@ -2237,8 +2248,7 @@ public final class ProcessList { int userId = UserHandle.getUserId(uid); StorageManagerInternal storageManagerInternal = LocalServices.getService( StorageManagerInternal.class); - if (mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid) - && !storageManagerInternal.isExternalStorageService(uid)) { + if (needsStorageDataIsolation(storageManagerInternal, app)) { bindMountAppStorageDirs = true; if (pkgDataInfoMap == null || !storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(), diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 61ebc361b6af..a1ec07cda8a8 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -261,9 +261,9 @@ class ProcessRecord implements WindowProcessListener { // Controller for error dialogs private final ErrorDialogController mDialogController = new ErrorDialogController(); // Controller for driving the process state on the window manager side. - final private WindowProcessController mWindowProcessController; + private final WindowProcessController mWindowProcessController; // all ServiceRecord running in this process - final ArraySet<ServiceRecord> services = new ArraySet<>(); + private final ArraySet<ServiceRecord> mServices = new ArraySet<>(); // services that are currently executing code (need to remain foreground). final ArraySet<ServiceRecord> executingServices = new ArraySet<>(); // All ConnectionRecord this process holds @@ -577,10 +577,10 @@ class ProcessRecord implements WindowProcessListener { pw.println(Arrays.toString(isolatedEntryPointArgs)); } mWindowProcessController.dump(pw, prefix); - if (services.size() > 0) { + if (mServices.size() > 0) { pw.print(prefix); pw.println("Services:"); - for (int i=0; i<services.size(); i++) { - pw.print(prefix); pw.print(" - "); pw.println(services.valueAt(i)); + for (int i = 0; i < mServices.size(); i++) { + pw.print(prefix); pw.print(" - "); pw.println(mServices.valueAt(i)); } } if (executingServices.size() > 0) { @@ -735,6 +735,60 @@ class ProcessRecord implements WindowProcessListener { } } + /** + * Records a service as running in the process. Note that this method does not actually start + * the service, but records the service as started for bookkeeping. + * + * @return true if the service was added, false otherwise. + */ + boolean startService(ServiceRecord record) { + if (record == null) { + return false; + } + boolean added = mServices.add(record); + if (added && record.serviceInfo != null) { + mWindowProcessController.onServiceStarted(record.serviceInfo); + } + return added; + } + + /** + * Records a service as stopped. Note that like {@link #startService(ServiceRecord)} this method + * does not actually stop the service, but records the service as stopped for bookkeeping. + * + * @return true if the service was removed, false otherwise. + */ + boolean stopService(ServiceRecord record) { + return mServices.remove(record); + } + + /** + * The same as calling {@link #stopService(ServiceRecord)} on all current running services. + */ + void stopAllServices() { + mServices.clear(); + } + + /** + * Returns the number of services added with {@link #startService(ServiceRecord)} and not yet + * removed by a call to {@link #stopService(ServiceRecord)} or {@link #stopAllServices()}. + * + * @see #startService(ServiceRecord) + * @see #stopService(ServiceRecord) + */ + int numberOfRunningServices() { + return mServices.size(); + } + + /** + * Returns the service at the specified {@code index}. + * + * @see #numberOfRunningServices() + */ + ServiceRecord getRunningServiceAt(int index) { + return mServices.valueAt(index); + } + void setCached(boolean cached) { if (mCached != cached) { mCached = cached; @@ -768,9 +822,9 @@ class ProcessRecord implements WindowProcessListener { return true; } - final int servicesSize = services.size(); + final int servicesSize = mServices.size(); for (int i = 0; i < servicesSize; i++) { - ServiceRecord r = services.valueAt(i); + ServiceRecord r = mServices.valueAt(i); if (r.isForeground) { return true; } @@ -1289,16 +1343,16 @@ class ProcessRecord implements WindowProcessListener { } void updateBoundClientUids() { - if (services.isEmpty()) { + if (mServices.isEmpty()) { clearBoundClientUids(); return; } // grab a set of clientUids of all connections of all services ArraySet<Integer> boundClientUids = new ArraySet<>(); - final int K = services.size(); - for (int j = 0; j < K; j++) { + final int serviceCount = mServices.size(); + for (int j = 0; j < serviceCount; j++) { ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns = - services.valueAt(j).getConnections(); + mServices.valueAt(j).getConnections(); final int N = conns.size(); for (int conni = 0; conni < N; conni++) { ArrayList<ConnectionRecord> c = conns.valueAt(conni); diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 546025a2498f..c7c25102343b 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -162,9 +162,6 @@ class UserController implements Handler.Callback { // when it never calls back. private static final int USER_SWITCH_CALLBACKS_TIMEOUT_MS = 5 * 1000; - // TODO(b/149604218): STOPSHIP remove this constant and the logcat - private static final boolean TESTS_NEED_LOGCAT = true; - // Used for statsd logging with UserLifecycleJourneyReported + UserLifecycleEventOccurred atoms private static final long INVALID_SESSION_ID = 0; @@ -1721,9 +1718,6 @@ class UserController implements Handler.Callback { } void continueUserSwitch(UserState uss, int oldUserId, int newUserId) { - if (TESTS_NEED_LOGCAT) { - Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId); - } EventLog.writeEvent(EventLogTags.UC_CONTINUE_USER_SWITCH, oldUserId, newUserId); if (isUserSwitchUiEnabled()) { @@ -1877,8 +1871,10 @@ class UserController implements Handler.Callback { builder.append("; this requires "); builder.append(INTERACT_ACROSS_USERS_FULL); if (allowMode != ALLOW_FULL_ONLY) { - builder.append(" or "); - builder.append(INTERACT_ACROSS_USERS); + if (allowMode == ALLOW_NON_FULL || isSameProfileGroup) { + builder.append(" or "); + builder.append(INTERACT_ACROSS_USERS); + } if (isSameProfileGroup && allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) { builder.append(" or "); diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index c2c79d361996..032ad63a8570 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -30,6 +30,7 @@ import android.media.AudioRoutesInfo; import android.media.AudioSystem; import android.media.IAudioRoutesObserver; import android.media.IStrategyPreferredDeviceDispatcher; +import android.media.MediaMetrics; import android.os.Binder; import android.os.Handler; import android.os.IBinder; @@ -668,6 +669,13 @@ import java.io.PrintWriter; } AudioService.sForceUseLogger.log( new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource)); + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE + MediaMetrics.SEPARATOR + + AudioSystem.forceUseUsageToString(useCase)) + .set(MediaMetrics.Property.EVENT, "onSetForceUse") + .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource) + .set(MediaMetrics.Property.FORCE_USE_MODE, + AudioSystem.forceUseConfigToString(config)) + .record(); AudioSystem.setForceUse(useCase, config); } diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java index c17ed3e292ef..3e97a1e136c6 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java +++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java @@ -33,6 +33,7 @@ import android.media.AudioRoutesInfo; import android.media.AudioSystem; import android.media.IAudioRoutesObserver; import android.media.IStrategyPreferredDeviceDispatcher; +import android.media.MediaMetrics; import android.os.Binder; import android.os.RemoteCallbackList; import android.os.RemoteException; @@ -64,10 +65,69 @@ public class AudioDeviceInventory { // lock to synchronize all access to mConnectedDevices and mApmConnectedDevices private final Object mDevicesLock = new Object(); + //Audio Analytics ids. + private static final String mMetricsId = "audio.device."; + // List of connected devices // Key for map created from DeviceInfo.makeDeviceListKey() @GuardedBy("mDevicesLock") - private final LinkedHashMap<String, DeviceInfo> mConnectedDevices = new LinkedHashMap<>(); + private final LinkedHashMap<String, DeviceInfo> mConnectedDevices = new LinkedHashMap<>() { + @Override + public DeviceInfo put(String key, DeviceInfo value) { + final DeviceInfo result = super.put(key, value); + record("put", true /* connected */, key, value); + return result; + } + + @Override + public DeviceInfo putIfAbsent(String key, DeviceInfo value) { + final DeviceInfo result = super.putIfAbsent(key, value); + if (result == null) { + record("putIfAbsent", true /* connected */, key, value); + } + return result; + } + + @Override + public DeviceInfo remove(Object key) { + final DeviceInfo result = super.remove(key); + if (result != null) { + record("remove", false /* connected */, (String) key, result); + } + return result; + } + + @Override + public boolean remove(Object key, Object value) { + final boolean result = super.remove(key, value); + if (result) { + record("remove", false /* connected */, (String) key, (DeviceInfo) value); + } + return result; + } + + // Not overridden + // clear + // compute + // computeIfAbsent + // computeIfPresent + // merge + // putAll + // replace + // replaceAll + private void record(String event, boolean connected, String key, DeviceInfo value) { + // DeviceInfo - int mDeviceType; + // DeviceInfo - int mDeviceCodecFormat; + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE + + MediaMetrics.SEPARATOR + AudioSystem.getDeviceName(value.mDeviceType)) + .set(MediaMetrics.Property.ADDRESS, value.mDeviceAddress) + .set(MediaMetrics.Property.EVENT, event) + .set(MediaMetrics.Property.NAME, value.mDeviceName) + .set(MediaMetrics.Property.STATE, connected + ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED) + .record(); + } + }; // List of devices actually connected to AudioPolicy (through AudioSystem), only one // by device type, which is used as the key, value is the DeviceInfo generated key. @@ -236,6 +296,16 @@ public class AudioDeviceInventory { + " codec=" + a2dpCodec + " vol=" + a2dpVolume)); + new MediaMetrics.Item(mMetricsId + "a2dp") + .set(MediaMetrics.Property.ADDRESS, address) + .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(a2dpCodec)) + .set(MediaMetrics.Property.EVENT, "onSetA2dpSinkConnectionState") + .set(MediaMetrics.Property.INDEX, a2dpVolume) + .set(MediaMetrics.Property.STATE, + state == BluetoothProfile.STATE_CONNECTED + ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED) + .record(); + synchronized (mDevicesLock) { final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, btDevice.getAddress()); @@ -284,6 +354,15 @@ public class AudioDeviceInventory { final DeviceInfo di = mConnectedDevices.get(key); boolean isConnected = di != null; + new MediaMetrics.Item(mMetricsId + "onSetA2dpSourceConnectionState") + .set(MediaMetrics.Property.ADDRESS, address) + .set(MediaMetrics.Property.DEVICE, + AudioSystem.getDeviceName(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP)) + .set(MediaMetrics.Property.STATE, + state == BluetoothProfile.STATE_CONNECTED + ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED) + .record(); + if (isConnected && state != BluetoothProfile.STATE_CONNECTED) { makeA2dpSrcUnavailable(address); } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) { @@ -301,6 +380,17 @@ public class AudioDeviceInventory { AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( "onSetHearingAidConnectionState addr=" + address)); + new MediaMetrics.Item(mMetricsId + "onSetHearingAidConnectionState") + .set(MediaMetrics.Property.ADDRESS, address) + .set(MediaMetrics.Property.DEVICE, + AudioSystem.getDeviceName(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP)) + .set(MediaMetrics.Property.STATE, + state == BluetoothProfile.STATE_CONNECTED + ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED) + .set(MediaMetrics.Property.STREAM_TYPE, + AudioSystem.streamToString(streamType)) + .record(); + synchronized (mDevicesLock) { final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID, btDevice.getAddress()); @@ -317,10 +407,15 @@ public class AudioDeviceInventory { } @GuardedBy("AudioDeviceBroker.mDeviceStateLock") - /*package*/ void onBluetoothA2dpActiveDeviceChange( + /*package*/ void onBluetoothA2dpActiveDeviceChange( @NonNull BtHelper.BluetoothA2dpDeviceInfo btInfo, int event) { + MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + + "onBluetoothA2dpActiveDeviceChange") + .set(MediaMetrics.Property.EVENT, BtHelper.a2dpDeviceEventToString(event)); + final BluetoothDevice btDevice = btInfo.getBtDevice(); if (btDevice == null) { + mmi.set(MediaMetrics.Property.EARLY_RETURN, "btDevice null").record(); return; } if (AudioService.DEBUG_DEVICES) { @@ -341,6 +436,8 @@ public class AudioDeviceInventory { if (mDeviceBroker.hasScheduledA2dpSinkConnectionState(btDevice)) { AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( "A2dp config change ignored (scheduled connection change)")); + mmi.set(MediaMetrics.Property.EARLY_RETURN, "A2dp config change ignored") + .record(); return; } final String key = DeviceInfo.makeDeviceListKey( @@ -348,9 +445,16 @@ public class AudioDeviceInventory { final DeviceInfo di = mConnectedDevices.get(key); if (di == null) { Log.e(TAG, "invalid null DeviceInfo in onBluetoothA2dpActiveDeviceChange"); + mmi.set(MediaMetrics.Property.EARLY_RETURN, "null DeviceInfo").record(); return; } + mmi.set(MediaMetrics.Property.ADDRESS, address) + .set(MediaMetrics.Property.ENCODING, + AudioSystem.audioFormatToString(a2dpCodec)) + .set(MediaMetrics.Property.INDEX, a2dpVolume) + .set(MediaMetrics.Property.NAME, di.mDeviceName); + if (event == BtHelper.EVENT_ACTIVE_DEVICE_CHANGE) { // Device is connected if (a2dpVolume != -1) { @@ -388,6 +492,7 @@ public class AudioDeviceInventory { + address + " codec=" + a2dpCodec).printLog(TAG)); } } + mmi.record(); } /*package*/ void onMakeA2dpDeviceUnavailableNow(String address, int a2dpCodec) { @@ -399,6 +504,9 @@ public class AudioDeviceInventory { /*package*/ void onReportNewRoutes() { int n = mRoutesObservers.beginBroadcast(); if (n > 0) { + new MediaMetrics.Item(mMetricsId + "onReportNewRoutes") + .set(MediaMetrics.Property.OBSERVERS, n) + .record(); AudioRoutesInfo routes; synchronized (mCurAudioRoutes) { routes = new AudioRoutesInfo(mCurAudioRoutes); @@ -428,6 +536,13 @@ public class AudioDeviceInventory { AudioDeviceInventory.WiredDeviceConnectionState wdcs) { AudioService.sDeviceLogger.log(new AudioServiceEvents.WiredDevConnectEvent(wdcs)); + MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + + "onSetWiredDeviceConnectionState") + .set(MediaMetrics.Property.ADDRESS, wdcs.mAddress) + .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(wdcs.mType)) + .set(MediaMetrics.Property.STATE, + wdcs.mState == AudioService.CONNECTION_STATE_DISCONNECTED + ? MediaMetrics.Value.DISCONNECTED : MediaMetrics.Value.CONNECTED); synchronized (mDevicesLock) { if ((wdcs.mState == AudioService.CONNECTION_STATE_DISCONNECTED) && DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.contains(wdcs.mType)) { @@ -438,6 +553,8 @@ public class AudioDeviceInventory { if (!handleDeviceConnection(wdcs.mState == AudioService.CONNECTION_STATE_CONNECTED, wdcs.mType, wdcs.mAddress, wdcs.mName)) { // change of connection state failed, bailout + mmi.set(MediaMetrics.Property.EARLY_RETURN, "change of connection state failed") + .record(); return; } if (wdcs.mState != AudioService.CONNECTION_STATE_DISCONNECTED) { @@ -453,15 +570,20 @@ public class AudioDeviceInventory { sendDeviceConnectionIntent(wdcs.mType, wdcs.mState, wdcs.mAddress, wdcs.mName); updateAudioRoutes(wdcs.mType, wdcs.mState); } + mmi.record(); } /*package*/ void onToggleHdmi() { + MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "onToggleHdmi") + .set(MediaMetrics.Property.DEVICE, + AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HDMI)); synchronized (mDevicesLock) { // Is HDMI connected? final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HDMI, ""); final DeviceInfo di = mConnectedDevices.get(key); if (di == null) { Log.e(TAG, "invalid null DeviceInfo in onToggleHdmi"); + mmi.set(MediaMetrics.Property.EARLY_RETURN, "invalid null DeviceInfo").record(); return; } // Toggle HDMI to retrigger broadcast with proper formats. @@ -472,6 +594,7 @@ public class AudioDeviceInventory { AudioSystem.DEVICE_STATE_AVAILABLE, "", "", "android"); // reconnect } + mmi.record(); } /*package*/ void onSaveSetPreferredDevice(int strategy, @NonNull AudioDeviceAttributes device) { @@ -535,6 +658,12 @@ public class AudioDeviceInventory { + Integer.toHexString(device) + " address:" + address + " name:" + deviceName + ")"); } + MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "handleDeviceConnection") + .set(MediaMetrics.Property.ADDRESS, address) + .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(device)) + .set(MediaMetrics.Property.MODE, connect + ? MediaMetrics.Value.CONNECT : MediaMetrics.Value.DISCONNECT) + .set(MediaMetrics.Property.NAME, deviceName); synchronized (mDevicesLock) { final String deviceKey = DeviceInfo.makeDeviceListKey(device, address); if (AudioService.DEBUG_DEVICES) { @@ -550,13 +679,18 @@ public class AudioDeviceInventory { AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName, AudioSystem.AUDIO_FORMAT_DEFAULT); if (res != AudioSystem.AUDIO_STATUS_OK) { - Slog.e(TAG, "not connecting device 0x" + Integer.toHexString(device) - + " due to command error " + res); + final String reason = "not connecting device 0x" + Integer.toHexString(device) + + " due to command error " + res; + Slog.e(TAG, reason); + mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) + .set(MediaMetrics.Property.STATE, MediaMetrics.Value.DISCONNECTED) + .record(); return false; } mConnectedDevices.put(deviceKey, new DeviceInfo( device, deviceName, address, AudioSystem.AUDIO_FORMAT_DEFAULT)); mDeviceBroker.postAccessoryPlugMediaUnmute(device); + mmi.set(MediaMetrics.Property.STATE, MediaMetrics.Value.CONNECTED).record(); return true; } else if (!connect && isConnected) { mAudioSystem.setDeviceConnectionState(device, @@ -564,11 +698,13 @@ public class AudioDeviceInventory { AudioSystem.AUDIO_FORMAT_DEFAULT); // always remove even if disconnection failed mConnectedDevices.remove(deviceKey); + mmi.set(MediaMetrics.Property.STATE, MediaMetrics.Value.CONNECTED).record(); return true; } Log.w(TAG, "handleDeviceConnection() failed, deviceKey=" + deviceKey + ", deviceSpec=" + di + ", connect=" + connect); } + mmi.set(MediaMetrics.Property.STATE, MediaMetrics.Value.DISCONNECTED).record(); return false; } @@ -582,6 +718,8 @@ public class AudioDeviceInventory { toRemove.add(deviceInfo.mDeviceAddress); } }); + new MediaMetrics.Item(mMetricsId + "disconnectA2dp") + .record(); if (toRemove.size() > 0) { final int delay = checkSendBecomingNoisyIntentInt( AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, @@ -602,6 +740,8 @@ public class AudioDeviceInventory { toRemove.add(deviceInfo.mDeviceAddress); } }); + new MediaMetrics.Item(mMetricsId + "disconnectA2dpSink") + .record(); toRemove.stream().forEach(deviceAddress -> makeA2dpSrcUnavailable(deviceAddress)); } } @@ -615,6 +755,8 @@ public class AudioDeviceInventory { toRemove.add(deviceInfo.mDeviceAddress); } }); + new MediaMetrics.Item(mMetricsId + "disconnectHearingAid") + .record(); if (toRemove.size() > 0) { final int delay = checkSendBecomingNoisyIntentInt( AudioSystem.DEVICE_OUT_HEARING_AID, 0, AudioSystem.DEVICE_NONE); @@ -743,6 +885,8 @@ public class AudioDeviceInventory { final int res = mAudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, AudioSystem.DEVICE_STATE_AVAILABLE, address, name, a2dpCodec); + // TODO: log in MediaMetrics once distinction between connection failure and + // double connection is made. if (res != AudioSystem.AUDIO_STATUS_OK) { AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( "APM failed to make available A2DP device addr=" + address @@ -771,7 +915,12 @@ public class AudioDeviceInventory { @GuardedBy("mDevicesLock") private void makeA2dpDeviceUnavailableNow(String address, int a2dpCodec) { + MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "a2dp." + address) + .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(a2dpCodec)) + .set(MediaMetrics.Property.EVENT, "makeA2dpDeviceUnavailableNow"); + if (address == null) { + mmi.set(MediaMetrics.Property.EARLY_RETURN, "address null").record(); return; } final String deviceToRemoveKey = @@ -783,6 +932,9 @@ public class AudioDeviceInventory { // removing A2DP device not currently used by AudioPolicy, log but don't act on it AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent( "A2DP device " + address + " made unavailable, was not used")).printLog(TAG)); + mmi.set(MediaMetrics.Property.EARLY_RETURN, + "A2DP device made unavailable, was not used") + .record(); return; } @@ -804,6 +956,7 @@ public class AudioDeviceInventory { mApmConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP); // Remove A2DP routes as well setCurrentAudioRouteNameIfPossible(null); + mmi.record(); } @GuardedBy("mDevicesLock") @@ -862,6 +1015,14 @@ public class AudioDeviceInventory { mDeviceBroker.postApplyVolumeOnDevice(streamType, AudioSystem.DEVICE_OUT_HEARING_AID, "makeHearingAidDeviceAvailable"); setCurrentAudioRouteNameIfPossible(name); + new MediaMetrics.Item(mMetricsId + "makeHearingAidDeviceAvailable") + .set(MediaMetrics.Property.ADDRESS, address != null ? address : "") + .set(MediaMetrics.Property.DEVICE, + AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HEARING_AID)) + .set(MediaMetrics.Property.NAME, name) + .set(MediaMetrics.Property.STREAM_TYPE, + AudioSystem.streamToString(streamType)) + .record(); } @GuardedBy("mDevicesLock") @@ -873,6 +1034,11 @@ public class AudioDeviceInventory { DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID, address)); // Remove Hearing Aid routes as well setCurrentAudioRouteNameIfPossible(null); + new MediaMetrics.Item(mMetricsId + "makeHearingAidDeviceUnavailable") + .set(MediaMetrics.Property.ADDRESS, address != null ? address : "") + .set(MediaMetrics.Property.DEVICE, + AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HEARING_AID)) + .record(); } @GuardedBy("mDevicesLock") @@ -919,10 +1085,18 @@ public class AudioDeviceInventory { @GuardedBy("mDevicesLock") private int checkSendBecomingNoisyIntentInt(int device, @AudioService.ConnectionState int state, int musicDevice) { + MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + + "checkSendBecomingNoisyIntentInt") + .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(device)) + .set(MediaMetrics.Property.STATE, + state == AudioService.CONNECTION_STATE_CONNECTED + ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED); if (state != AudioService.CONNECTION_STATE_DISCONNECTED) { + mmi.set(MediaMetrics.Property.DELAY_MS, 0).record(); // OK to return return 0; } if (!BECOMING_NOISY_INTENT_DEVICES_SET.contains(device)) { + mmi.set(MediaMetrics.Property.DELAY_MS, 0).record(); // OK to return return 0; } int delay = 0; @@ -950,12 +1124,14 @@ public class AudioDeviceInventory { // the pausing of some apps that are playing remotely AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent( "dropping ACTION_AUDIO_BECOMING_NOISY")).printLog(TAG)); + mmi.set(MediaMetrics.Property.DELAY_MS, 0).record(); // OK to return return 0; } mDeviceBroker.postBroadcastBecomingNoisy(); delay = AudioService.BECOMING_NOISY_DELAY_MS; } + mmi.set(MediaMetrics.Property.DELAY_MS, delay).record(); return delay; } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index f840f2d359d5..7cac376ea7ae 100755 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -88,6 +88,7 @@ import android.media.IStrategyPreferredDeviceDispatcher; import android.media.IVolumeController; import android.media.MediaExtractor; import android.media.MediaFormat; +import android.media.MediaMetrics; import android.media.PlayerBase; import android.media.VolumePolicy; import android.media.audiofx.AudioEffect; @@ -1880,6 +1881,16 @@ public class AudioService extends IAudioService.Stub synchronized (mExtVolumeControllerLock) { extVolCtlr = mExtVolumeController; } + new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume") + .setUid(Binder.getCallingUid()) + .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) + .set(MediaMetrics.Property.CLIENT_NAME, caller) + .set(MediaMetrics.Property.DIRECTION, direction > 0 + ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN) + .set(MediaMetrics.Property.EXTERNAL, extVolCtlr != null + ? MediaMetrics.Value.YES : MediaMetrics.Value.NO) + .set(MediaMetrics.Property.FLAGS, flags) + .record(); if (extVolCtlr != null) { sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE, direction, 0 /*ignored*/, @@ -3141,21 +3152,32 @@ public class AudioService extends IAudioService.Stub if (uid == android.os.Process.SYSTEM_UID) { uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); } + MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) + .setUid(uid) + .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) + .set(MediaMetrics.Property.EVENT, "setMicrophoneMute") + .set(MediaMetrics.Property.REQUEST, on + ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE); + // If OP_MUTE_MICROPHONE is set, disallow unmuting. if (!on && mAppOps.noteOp(AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage) != AppOpsManager.MODE_ALLOWED) { + mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record(); return; } if (!checkAudioSettingsPermission("setMicrophoneMute()")) { + mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record(); return; } if (userId != UserHandle.getCallingUserId() && mContext.checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { + mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record(); return; } mMicMuteFromApi = on; + mmi.record(); // record now, the no caller check will set the mute state. setMicrophoneMuteNoCallerCheck(userId); } @@ -3167,6 +3189,12 @@ public class AudioService extends IAudioService.Stub return; } mMicMuteFromSwitch = on; + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) + .setUid(userId) + .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch") + .set(MediaMetrics.Property.REQUEST, on + ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) + .record(); setMicrophoneMuteNoCallerCheck(userId); } @@ -3207,6 +3235,17 @@ public class AudioService extends IAudioService.Stub Log.e(TAG, "Error changing mic mute state to " + muted + " current:" + mMicMuteFromSystemCached); } + + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) + .setUid(userId) + .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck") + .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached + ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) + .set(MediaMetrics.Property.REQUEST, muted + ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) + .set(MediaMetrics.Property.STATUS, ret) + .record(); + try { // send the intent even if there was a failure to change the actual mute state: // the AudioManager.setMicrophoneMute API doesn't have a return value to @@ -3941,10 +3980,20 @@ public class AudioService extends IAudioService.Stub } // for logging only + final int uid = Binder.getCallingUid(); + final int pid = Binder.getCallingPid(); final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on) - .append(") from u/pid:").append(Binder.getCallingUid()).append("/") - .append(Binder.getCallingPid()).toString(); + .append(") from u/pid:").append(uid).append("/") + .append(pid).toString(); final boolean stateChanged = mDeviceBroker.setSpeakerphoneOn(on, eventSource); + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE + + MediaMetrics.SEPARATOR + "setSpeakerphoneOn") + .setUid(uid) + .setPid(pid) + .set(MediaMetrics.Property.STATE, on + ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) + .record(); + if (stateChanged) { final long ident = Binder.clearCallingIdentity(); try { @@ -3975,9 +4024,19 @@ public class AudioService extends IAudioService.Stub } // for logging only + final int uid = Binder.getCallingUid(); + final int pid = Binder.getCallingPid(); final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on) - .append(") from u/pid:").append(Binder.getCallingUid()).append("/") - .append(Binder.getCallingPid()).toString(); + .append(") from u/pid:").append(uid).append("/").append(pid).toString(); + + //bt sco + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE + + MediaMetrics.SEPARATOR + "setBluetoothScoOn") + .setUid(uid) + .setPid(pid) + .set(MediaMetrics.Property.STATE, on + ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) + .record(); mDeviceBroker.setBluetoothScoOn(on, eventSource); } @@ -3993,9 +4052,20 @@ public class AudioService extends IAudioService.Stub /** @see AudioManager#setBluetoothA2dpOn(boolean) */ public void setBluetoothA2dpOn(boolean on) { // for logging only + final int uid = Binder.getCallingUid(); + final int pid = Binder.getCallingPid(); final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on) - .append(") from u/pid:").append(Binder.getCallingUid()).append("/") - .append(Binder.getCallingPid()).toString(); + .append(") from u/pid:").append(uid).append("/") + .append(pid).toString(); + + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE + + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn") + .setUid(uid) + .setPid(pid) + .set(MediaMetrics.Property.STATE, on + ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) + .record(); + mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource); } @@ -4006,31 +4076,59 @@ public class AudioService extends IAudioService.Stub /** @see AudioManager#startBluetoothSco() */ public void startBluetoothSco(IBinder cb, int targetSdkVersion) { + final int uid = Binder.getCallingUid(); + final int pid = Binder.getCallingPid(); final int scoAudioMode = (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED; final String eventSource = new StringBuilder("startBluetoothSco()") - .append(") from u/pid:").append(Binder.getCallingUid()).append("/") - .append(Binder.getCallingPid()).toString(); + .append(") from u/pid:").append(uid).append("/") + .append(pid).toString(); + + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) + .setUid(uid) + .setPid(pid) + .set(MediaMetrics.Property.EVENT, "startBluetoothSco") + .set(MediaMetrics.Property.SCO_AUDIO_MODE, + BtHelper.scoAudioModeToString(scoAudioMode)) + .record(); startBluetoothScoInt(cb, scoAudioMode, eventSource); + } /** @see AudioManager#startBluetoothScoVirtualCall() */ public void startBluetoothScoVirtualCall(IBinder cb) { + final int uid = Binder.getCallingUid(); + final int pid = Binder.getCallingPid(); final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()") - .append(") from u/pid:").append(Binder.getCallingUid()).append("/") - .append(Binder.getCallingPid()).toString(); + .append(") from u/pid:").append(uid).append("/") + .append(pid).toString(); + + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) + .setUid(uid) + .setPid(pid) + .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall") + .set(MediaMetrics.Property.SCO_AUDIO_MODE, + BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL)) + .record(); startBluetoothScoInt(cb, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource); } void startBluetoothScoInt(IBinder cb, int scoAudioMode, @NonNull String eventSource) { + MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) + .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt") + .set(MediaMetrics.Property.SCO_AUDIO_MODE, + BtHelper.scoAudioModeToString(scoAudioMode)); + if (!checkAudioSettingsPermission("startBluetoothSco()") || !mSystemReady) { + mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record(); return; } synchronized (mDeviceBroker.mSetModeLock) { mDeviceBroker.startBluetoothScoForClient_Sync(cb, scoAudioMode, eventSource); } + mmi.record(); } /** @see AudioManager#stopBluetoothSco() */ @@ -4039,12 +4137,21 @@ public class AudioService extends IAudioService.Stub !mSystemReady) { return; } + final int uid = Binder.getCallingUid(); + final int pid = Binder.getCallingPid(); final String eventSource = new StringBuilder("stopBluetoothSco()") - .append(") from u/pid:").append(Binder.getCallingUid()).append("/") - .append(Binder.getCallingPid()).toString(); + .append(") from u/pid:").append(uid).append("/") + .append(pid).toString(); synchronized (mDeviceBroker.mSetModeLock) { mDeviceBroker.stopBluetoothScoForClient_Sync(cb, eventSource); } + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) + .setUid(uid) + .setPid(pid) + .set(MediaMetrics.Property.EVENT, "stopBluetoothSco") + .set(MediaMetrics.Property.SCO_AUDIO_MODE, + BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED)) + .record(); } @@ -4806,6 +4913,14 @@ public class AudioService extends IAudioService.Stub && state != CONNECTION_STATE_DISCONNECTED) { throw new IllegalArgumentException("Invalid state " + state); } + new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState") + .set(MediaMetrics.Property.ADDRESS, address) + .set(MediaMetrics.Property.CLIENT_NAME, caller) + .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(type)) + .set(MediaMetrics.Property.NAME, name) + .set(MediaMetrics.Property.STATE, + state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected") + .record(); mDeviceBroker.setWiredDeviceConnectionState(type, state, address, name, caller); } @@ -5266,7 +5381,32 @@ public class AudioService extends IAudioService.Stub private String mVolumeIndexSettingName; private int mObservedDevices; - private final SparseIntArray mIndexMap = new SparseIntArray(8); + private final SparseIntArray mIndexMap = new SparseIntArray(8) { + @Override + public void put(int key, int value) { + super.put(key, value); + record("put", key, value); + } + @Override + public void setValueAt(int index, int value) { + super.setValueAt(index, value); + record("setValueAt", keyAt(index), value); + } + + // Record all changes in the VolumeStreamState + private void record(String event, int key, int value) { + final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default" + : AudioSystem.getOutputDeviceName(key); + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR + + AudioSystem.streamToString(mStreamType) + + "." + device) + .set(MediaMetrics.Property.EVENT, event) + .set(MediaMetrics.Property.INDEX, value) + .set(MediaMetrics.Property.MIN_INDEX, mIndexMin) + .set(MediaMetrics.Property.MAX_INDEX, mIndexMax) + .record(); + } + }; private final Intent mVolumeChanged; private final Intent mStreamDevicesChanged; @@ -5949,6 +6089,13 @@ public class AudioService extends IAudioService.Stub + eventSource); break; } + new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE + + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase)) + .set(MediaMetrics.Property.EVENT, "setForceUse") + .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource) + .set(MediaMetrics.Property.FORCE_USE_MODE, + AudioSystem.forceUseConfigToString(config)) + .record(); sForceUseLogger.log( new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource)); AudioSystem.setForceUse(useCase, config); @@ -6450,23 +6597,42 @@ public class AudioService extends IAudioService.Stub public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, IAudioPolicyCallback pcb, int sdk) { + final int uid = Binder.getCallingUid(); + MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") + .setUid(uid) + //.putInt("durationHint", durationHint) + .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) + .set(MediaMetrics.Property.CLIENT_NAME, clientId) + .set(MediaMetrics.Property.EVENT, "requestAudioFocus") + .set(MediaMetrics.Property.FLAGS, flags); + // permission checks if (aa != null && !isValidAudioAttributesUsage(aa)) { - Log.w(TAG, "Request using unsupported usage."); + final String reason = "Request using unsupported usage"; + Log.w(TAG, reason); + mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) + .record(); return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) { if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) { if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( android.Manifest.permission.MODIFY_PHONE_STATE)) { - Log.e(TAG, "Invalid permission to (un)lock audio focus", new Exception()); + final String reason = "Invalid permission to (un)lock audio focus"; + Log.e(TAG, reason, new Exception()); + mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) + .record(); return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } } else { // only a registered audio policy can be used to lock focus synchronized (mAudioPolicies) { if (!mAudioPolicies.containsKey(pcb.asBinder())) { - Log.e(TAG, "Invalid unregistered AudioPolicy to (un)lock audio focus"); + final String reason = + "Invalid unregistered AudioPolicy to (un)lock audio focus"; + Log.e(TAG, reason); + mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) + .record(); return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } } @@ -6474,25 +6640,40 @@ public class AudioService extends IAudioService.Stub } if (callingPackageName == null || clientId == null || aa == null) { - Log.e(TAG, "Invalid null parameter to request audio focus"); + final String reason = "Invalid null parameter to request audio focus"; + Log.e(TAG, reason); + mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) + .record(); return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } - + mmi.record(); return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, clientId, callingPackageName, flags, sdk, - forceFocusDuckingForAccessibility(aa, durationHint, Binder.getCallingUid())); + forceFocusDuckingForAccessibility(aa, durationHint, uid)); } public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName) { + MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") + .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) + .set(MediaMetrics.Property.CLIENT_NAME, clientId) + .set(MediaMetrics.Property.EVENT, "abandonAudioFocus"); + if (aa != null && !isValidAudioAttributesUsage(aa)) { Log.w(TAG, "Request using unsupported usage."); + mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record(); + return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } + mmi.record(); return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); } public void unregisterAudioFocusClient(String clientId) { + new MediaMetrics.Item(mMetricsId + "focus") + .set(MediaMetrics.Property.CLIENT_NAME, clientId) + .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient") + .record(); mMediaFocusControl.unregisterAudioFocusClient(clientId); } @@ -7066,6 +7247,12 @@ public class AudioService extends IAudioService.Stub } } + /** + * Audio Analytics ids. + */ + private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE + + MediaMetrics.SEPARATOR; + private static String safeMediaVolumeStateToString(int state) { switch(state) { case SAFE_MEDIA_VOLUME_NOT_CONFIGURED: return "SAFE_MEDIA_VOLUME_NOT_CONFIGURED"; diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java index add620e74df0..591356746e38 100644 --- a/services/core/java/com/android/server/audio/AudioServiceEvents.java +++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java @@ -19,6 +19,7 @@ package com.android.server.audio; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioSystem; +import android.media.MediaMetrics; import com.android.server.audio.AudioDeviceInventory.WiredDeviceConnectionState; @@ -120,6 +121,7 @@ public class AudioServiceEvents { mCaller = caller; mGroupName = null; mAudioAttributes = null; + logMetricEvent(); } /** used for VOL_SET_HEARING_AID_VOL*/ @@ -132,6 +134,7 @@ public class AudioServiceEvents { mCaller = null; mGroupName = null; mAudioAttributes = null; + logMetricEvent(); } /** used for VOL_SET_AVRCP_VOL */ @@ -144,6 +147,7 @@ public class AudioServiceEvents { mCaller = null; mGroupName = null; mAudioAttributes = null; + logMetricEvent(); } /** used for VOL_VOICE_ACTIVITY_HEARING_AID */ @@ -156,6 +160,7 @@ public class AudioServiceEvents { mCaller = null; mGroupName = null; mAudioAttributes = null; + logMetricEvent(); } /** used for VOL_MODE_CHANGE_HEARING_AID */ @@ -168,6 +173,7 @@ public class AudioServiceEvents { mCaller = null; mGroupName = null; mAudioAttributes = null; + logMetricEvent(); } /** used for VOL_SET_GROUP_VOL */ @@ -179,6 +185,102 @@ public class AudioServiceEvents { mCaller = caller; mGroupName = group; mAudioAttributes = aa; + logMetricEvent(); + } + + + /** + * Audio Analytics unique Id. + */ + private static final String mMetricsId = MediaMetrics.Name.AUDIO_VOLUME_EVENT; + + /** + * Log mediametrics event + */ + private void logMetricEvent() { + switch (mOp) { + case VOL_ADJUST_SUGG_VOL: + case VOL_ADJUST_VOL_UID: + case VOL_ADJUST_STREAM_VOL: { + String eventName; + switch (mOp) { + case VOL_ADJUST_SUGG_VOL: + eventName = "adjustSuggestedStreamVolume"; + break; + case VOL_ADJUST_STREAM_VOL: + eventName = "adjustStreamVolume"; + break; + case VOL_ADJUST_VOL_UID: + eventName = "adjustStreamVolumeForUid"; + break; + default: + return; // not possible, just return here + } + new MediaMetrics.Item(mMetricsId) + .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) + .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down") + .set(MediaMetrics.Property.EVENT, eventName) + .set(MediaMetrics.Property.FLAGS, mVal2) + .set(MediaMetrics.Property.STREAM_TYPE, + AudioSystem.streamToString(mStream)) + .record(); + return; + } + case VOL_SET_STREAM_VOL: + new MediaMetrics.Item(mMetricsId) + .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) + .set(MediaMetrics.Property.EVENT, "setStreamVolume") + .set(MediaMetrics.Property.FLAGS, mVal2) + .set(MediaMetrics.Property.INDEX, mVal1) + .set(MediaMetrics.Property.STREAM_TYPE, + AudioSystem.streamToString(mStream)) + .record(); + return; + case VOL_SET_HEARING_AID_VOL: + new MediaMetrics.Item(mMetricsId) + .set(MediaMetrics.Property.EVENT, "setHearingAidVolume") + .set(MediaMetrics.Property.GAIN_DB, (double) mVal2) + .set(MediaMetrics.Property.INDEX, mVal1) + .record(); + return; + case VOL_SET_AVRCP_VOL: + new MediaMetrics.Item(mMetricsId) + .set(MediaMetrics.Property.EVENT, "setAvrcpVolume") + .set(MediaMetrics.Property.INDEX, mVal1) + .record(); + return; + case VOL_VOICE_ACTIVITY_HEARING_AID: + new MediaMetrics.Item(mMetricsId) + .set(MediaMetrics.Property.EVENT, "voiceActivityHearingAid") + .set(MediaMetrics.Property.INDEX, mVal1) + .set(MediaMetrics.Property.STATE, + mVal2 == 1 ? "active" : "inactive") + .set(MediaMetrics.Property.STREAM_TYPE, + AudioSystem.streamToString(mStream)) + .record(); + return; + case VOL_MODE_CHANGE_HEARING_AID: + new MediaMetrics.Item(mMetricsId) + .set(MediaMetrics.Property.EVENT, "modeChangeHearingAid") + .set(MediaMetrics.Property.INDEX, mVal1) + .set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mVal2)) + .set(MediaMetrics.Property.STREAM_TYPE, + AudioSystem.streamToString(mStream)) + .record(); + return; + case VOL_SET_GROUP_VOL: + new MediaMetrics.Item(mMetricsId) + .set(MediaMetrics.Property.ATTRIBUTES, mAudioAttributes.toString()) + .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) + .set(MediaMetrics.Property.EVENT, "setVolumeIndexForAttributes") + .set(MediaMetrics.Property.FLAGS, mVal2) + .set(MediaMetrics.Property.GROUP, mGroupName) + .set(MediaMetrics.Property.INDEX, mVal1) + .record(); + return; + default: + return; + } } @Override diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java index 93d1bede9de8..accb90cc3c0c 100644 --- a/services/core/java/com/android/server/audio/BtHelper.java +++ b/services/core/java/com/android/server/audio/BtHelper.java @@ -113,6 +113,24 @@ public class BtHelper { private static final int BT_HEARING_AID_GAIN_MIN = -128; + /** + * Returns a string representation of the scoAudioMode. + */ + public static String scoAudioModeToString(int scoAudioMode) { + switch (scoAudioMode) { + case SCO_MODE_UNDEFINED: + return "SCO_MODE_UNDEFINED"; + case SCO_MODE_VIRTUAL_CALL: + return "SCO_MODE_VIRTUAL_CALL"; + case SCO_MODE_RAW: + return "SCO_MODE_RAW"; + case SCO_MODE_VR: + return "SCO_MODE_VR"; + default: + return "SCO_MODE_(" + scoAudioMode + ")"; + } + } + //---------------------------------------------------------------------- /*package*/ static class BluetoothA2dpDeviceInfo { private final @NonNull BluetoothDevice mBtDevice; @@ -965,4 +983,27 @@ public class BtHelper { return AudioSystem.AUDIO_FORMAT_DEFAULT; } } + + /** + * Returns the String equivalent of the btCodecType. + * + * This uses an "ENCODING_" prefix for consistency with Audio; + * we could alternately use the "SOURCE_CODEC_TYPE_" prefix from Bluetooth. + */ + public static String bluetoothCodecToEncodingString(int btCodecType) { + switch (btCodecType) { + case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC: + return "ENCODING_SBC"; + case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC: + return "ENCODING_AAC"; + case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX: + return "ENCODING_APTX"; + case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD: + return "ENCODING_APTX_HD"; + case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC: + return "ENCODING_LDAC"; + default: + return "ENCODING_BT_CODEC_TYPE(" + btCodecType + ")"; + } + } } diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java index bfab9919258c..26281b739436 100755 --- a/services/core/java/com/android/server/audio/MediaFocusControl.java +++ b/services/core/java/com/android/server/audio/MediaFocusControl.java @@ -25,6 +25,7 @@ import android.media.AudioFocusInfo; import android.media.AudioManager; import android.media.AudioSystem; import android.media.IAudioFocusDispatcher; +import android.media.MediaMetrics; import android.media.audiopolicy.IAudioPolicyCallback; import android.os.Binder; import android.os.Build; @@ -144,6 +145,8 @@ public class MediaFocusControl implements PlayerFocusEnforcer { private static final AudioEventLogger mEventLogger = new AudioEventLogger(50, "focus commands as seen by MediaFocusControl"); + private static final String mMetricsId = MediaMetrics.Name.AUDIO_FOCUS; + /*package*/ void noFocusForSuspendedApp(@NonNull String packageName, int uid) { synchronized (mAudioFocusLock) { final Iterator<FocusRequester> stackIterator = mFocusStack.iterator(); @@ -818,6 +821,17 @@ public class MediaFocusControl implements PlayerFocusEnforcer { protected int requestAudioFocus(@NonNull AudioAttributes aa, int focusChangeHint, IBinder cb, IAudioFocusDispatcher fd, @NonNull String clientId, @NonNull String callingPackageName, int flags, int sdk, boolean forceDuck) { + new MediaMetrics.Item(mMetricsId) + .setUid(Binder.getCallingUid()) + .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) + .set(MediaMetrics.Property.CLIENT_NAME, clientId) + .set(MediaMetrics.Property.EVENT, "requestAudioFocus") + .set(MediaMetrics.Property.FLAGS, flags) + .set(MediaMetrics.Property.FOCUS_CHANGE_HINT, + AudioManager.audioFocusToString(focusChangeHint)) + //.set(MediaMetrics.Property.SDK, sdk) + .record(); + mEventLogger.log((new AudioEventLogger.StringEvent( "requestAudioFocus() from uid/pid " + Binder.getCallingUid() + "/" + Binder.getCallingPid() @@ -982,6 +996,13 @@ public class MediaFocusControl implements PlayerFocusEnforcer { * */ protected int abandonAudioFocus(IAudioFocusDispatcher fl, String clientId, AudioAttributes aa, String callingPackageName) { + new MediaMetrics.Item(mMetricsId) + .setUid(Binder.getCallingUid()) + .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) + .set(MediaMetrics.Property.CLIENT_NAME, clientId) + .set(MediaMetrics.Property.EVENT, "abandonAudioFocus") + .record(); + // AudioAttributes are currently ignored, to be used for zones / a11y mEventLogger.log((new AudioEventLogger.StringEvent( "abandonAudioFocus() from uid/pid " + Binder.getCallingUid() diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index f4d7f9ac5a5e..36d69c93c1cb 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -89,10 +89,8 @@ class AutomaticBrightnessController { private final BrightnessMappingStrategy mBrightnessMapper; // The minimum and maximum screen brightnesses. - private final int mScreenBrightnessRangeMinimum; - private final int mScreenBrightnessRangeMaximum; - private final float mScreenBrightnessRangeMinimumFloat; - private final float mScreenBrightnessRangeMaximumFloat; + private final float mScreenBrightnessRangeMinimum; + private final float mScreenBrightnessRangeMaximum; // How much to scale doze brightness by (should be (0, 1.0]). private final float mDozeScaleFactor; @@ -156,7 +154,6 @@ class AutomaticBrightnessController { // The screen brightness threshold at which to brighten or darken the screen. private float mScreenBrighteningThreshold; private float mScreenDarkeningThreshold; - // The most recent light sample. private float mLastObservedLux; @@ -177,8 +174,9 @@ class AutomaticBrightnessController { // We preserve this value even when we stop using the light sensor so // that we can quickly revert to the previous auto-brightness level // while the light sensor warms up. - // Use -1 if there is no current auto-brightness value available. - private int mScreenAutoBrightness = PowerManager.BRIGHTNESS_INVALID; + // Use PowerManager.BRIGHTNESS_INVALID_FLOAT if there is no current auto-brightness value + // available. + private float mScreenAutoBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; // The current display policy. This is useful, for example, for knowing when we're dozing, // where the light sensor may not be available. @@ -188,7 +186,7 @@ class AutomaticBrightnessController { // for the initial state of the sample. private boolean mBrightnessAdjustmentSamplePending; private float mBrightnessAdjustmentSampleOldLux; - private int mBrightnessAdjustmentSampleOldBrightness; + private float mBrightnessAdjustmentSampleOldBrightness; // When the short term model is invalidated, we don't necessarily reset it (i.e. clear the // user's adjustment) immediately, but wait for a drastic enough change in the ambient light. @@ -243,13 +241,8 @@ class AutomaticBrightnessController { mCallbacks = callbacks; mSensorManager = sensorManager; mBrightnessMapper = mapper; - mScreenBrightnessRangeMinimum = - BrightnessSynchronizer.brightnessFloatToInt(mContext, brightnessMin); - mScreenBrightnessRangeMaximum = - com.android.internal.BrightnessSynchronizer.brightnessFloatToInt( - mContext, brightnessMax); - mScreenBrightnessRangeMinimumFloat = brightnessMin; - mScreenBrightnessRangeMaximumFloat = brightnessMax; + mScreenBrightnessRangeMinimum = brightnessMin; + mScreenBrightnessRangeMaximum = brightnessMax; mLightSensorWarmUpTimeConfig = lightSensorWarmUpTime; mDozeScaleFactor = dozeScaleFactor; mNormalLightSensorRate = lightSensorRate; @@ -299,12 +292,12 @@ class AutomaticBrightnessController { return true; } - public int getAutomaticScreenBrightness() { + public float getAutomaticScreenBrightness() { if (!mAmbientLuxValid) { - return -1; + return PowerManager.BRIGHTNESS_INVALID_FLOAT; } if (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE) { - return Math.round(mScreenAutoBrightness * mDozeScaleFactor); + return mScreenAutoBrightness * mDozeScaleFactor; } return mScreenAutoBrightness; } @@ -385,7 +378,7 @@ class AutomaticBrightnessController { private boolean setScreenBrightnessByUser(float brightness) { if (!mAmbientLuxValid) { - // If we don't have a valid ambient lux then we don't have a valid brightness anyways, + // If we don't have a valid ambient lux then we don't have a valid brightness anyway, // and we can't use this data to add a new control point to the short-term model. return false; } @@ -486,7 +479,7 @@ class AutomaticBrightnessController { } else if (mLightSensorEnabled) { mLightSensorEnabled = false; mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig; - mScreenAutoBrightness = PowerManager.BRIGHTNESS_INVALID; + mScreenAutoBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; mRecentLightSamples = 0; mAmbientLightRingBuffer.clear(); mCurrentLightSensorRate = -1; @@ -735,29 +728,28 @@ class AutomaticBrightnessController { float value = mBrightnessMapper.getBrightness(mAmbientLux, mForegroundAppPackageName, mForegroundAppCategory); - int newScreenAutoBrightness = BrightnessSynchronizer.brightnessFloatToInt( - mContext, clampScreenBrightnessFloat(value)); + float newScreenAutoBrightness = clampScreenBrightness(value); // If screenAutoBrightness is set, we should have screen{Brightening,Darkening}Threshold, // in which case we ignore the new screen brightness if it doesn't differ enough from the // previous one. - if (mScreenAutoBrightness != -1 + if (!Float.isNaN(mScreenAutoBrightness) && !isManuallySet && newScreenAutoBrightness > mScreenDarkeningThreshold && newScreenAutoBrightness < mScreenBrighteningThreshold) { if (mLoggingEnabled) { - Slog.d(TAG, "ignoring newScreenAutoBrightness: " + mScreenDarkeningThreshold - + " < " + newScreenAutoBrightness + " < " + mScreenBrighteningThreshold); + Slog.d(TAG, "ignoring newScreenAutoBrightness: " + + mScreenDarkeningThreshold + " < " + newScreenAutoBrightness + + " < " + mScreenBrighteningThreshold); } return; } - - if (mScreenAutoBrightness != newScreenAutoBrightness) { + if (!BrightnessSynchronizer.floatEquals(mScreenAutoBrightness, + newScreenAutoBrightness)) { if (mLoggingEnabled) { - Slog.d(TAG, "updateAutoBrightness: " + - "mScreenAutoBrightness=" + mScreenAutoBrightness + ", " + - "newScreenAutoBrightness=" + newScreenAutoBrightness); + Slog.d(TAG, "updateAutoBrightness: " + + "mScreenAutoBrightness=" + mScreenAutoBrightness + ", " + + "newScreenAutoBrightness=" + newScreenAutoBrightness); } - mScreenAutoBrightness = newScreenAutoBrightness; mScreenBrighteningThreshold = clampScreenBrightness( mScreenBrightnessThresholds.getBrighteningThreshold(newScreenAutoBrightness)); @@ -770,19 +762,12 @@ class AutomaticBrightnessController { } } - // Clamps values with float range [1.0-255.0] - // TODO(brightnessfloat): convert everything that uses this to float system + // Clamps values with float range [0.0-1.0] private float clampScreenBrightness(float value) { return MathUtils.constrain(value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum); } - // Clamps values with float range [0.0-1.0] - private float clampScreenBrightnessFloat(float value) { - return MathUtils.constrain(value, - mScreenBrightnessRangeMinimumFloat, mScreenBrightnessRangeMaximumFloat); - } - private void prepareBrightnessAdjustmentSample() { if (!mBrightnessAdjustmentSamplePending) { mBrightnessAdjustmentSamplePending = true; @@ -806,12 +791,13 @@ class AutomaticBrightnessController { private void collectBrightnessAdjustmentSample() { if (mBrightnessAdjustmentSamplePending) { mBrightnessAdjustmentSamplePending = false; - if (mAmbientLuxValid && mScreenAutoBrightness >= 0) { + if (mAmbientLuxValid && (mScreenAutoBrightness >= PowerManager.BRIGHTNESS_MIN + || mScreenAutoBrightness == PowerManager.BRIGHTNESS_OFF_FLOAT)) { if (mLoggingEnabled) { - Slog.d(TAG, "Auto-brightness adjustment changed by user: " + - "lux=" + mAmbientLux + ", " + - "brightness=" + mScreenAutoBrightness + ", " + - "ring=" + mAmbientLightRingBuffer); + Slog.d(TAG, "Auto-brightness adjustment changed by user: " + + "lux=" + mAmbientLux + ", " + + "brightness=" + mScreenAutoBrightness + ", " + + "ring=" + mAmbientLightRingBuffer); } EventLog.writeEvent(EventLogTags.AUTO_BRIGHTNESS_ADJ, diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index b4f7cdbd5694..02d499fbd81f 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -28,6 +28,8 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOUL import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL; import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL; import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL; +import static android.view.Surface.ROTATION_270; +import static android.view.Surface.ROTATION_90; import android.Manifest; import android.annotation.NonNull; @@ -1363,8 +1365,7 @@ public final class DisplayManagerService extends SystemService { return null; } - private SurfaceControl.ScreenshotGraphicBuffer screenshotInternal(int displayId, - boolean captureSecureLayer) { + private SurfaceControl.ScreenshotGraphicBuffer systemScreenshotInternal(int displayId) { synchronized (mSyncRoot) { final IBinder token = getDisplayToken(displayId); if (token == null) { @@ -1376,15 +1377,42 @@ public final class DisplayManagerService extends SystemService { } final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked(); - if (captureSecureLayer) { - return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(token, new Rect(), - displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(), - false /* useIdentityTransform */, 0 /* rotation */); - } else { - return SurfaceControl.screenshotToBuffer(token, new Rect(), - displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(), - false /* useIdentityTransform */, 0 /* rotation */); + return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(token, new Rect(), + displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(), + false /* useIdentityTransform */, 0 /* rotation */); + } + } + + private SurfaceControl.ScreenshotGraphicBuffer userScreenshotInternal(int displayId) { + synchronized (mSyncRoot) { + final IBinder token = getDisplayToken(displayId); + if (token == null) { + return null; + } + final LogicalDisplay logicalDisplay = mLogicalDisplays.get(displayId); + if (logicalDisplay == null) { + return null; + } + + final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked(); + // Takes screenshot based on current device orientation. + final Display display = DisplayManagerGlobal.getInstance() + .getRealDisplay(displayId); + if (display == null) { + return null; } + final Point displaySize = new Point(); + display.getRealSize(displaySize); + + int rotation = displayInfo.rotation; + // TODO (b/153382624) : This workaround solution would be removed after + // SurfaceFlinger fixes the inconsistency with rotation direction issue. + if (rotation == ROTATION_90 || rotation == ROTATION_270) { + rotation = (rotation == ROTATION_90) ? ROTATION_270 : ROTATION_90; + } + + return SurfaceControl.screenshotToBuffer(token, new Rect(), displaySize.x, + displaySize.y, false /* useIdentityTransform */, rotation /* rotation */); } } @@ -2502,13 +2530,13 @@ public final class DisplayManagerService extends SystemService { } @Override - public SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId) { - return screenshotInternal(displayId, true); + public SurfaceControl.ScreenshotGraphicBuffer systemScreenshot(int displayId) { + return systemScreenshotInternal(displayId); } @Override - public SurfaceControl.ScreenshotGraphicBuffer screenshotWithoutSecureLayer(int displayId) { - return screenshotInternal(displayId, false); + public SurfaceControl.ScreenshotGraphicBuffer userScreenshot(int displayId) { + return userScreenshotInternal(displayId); } @Override diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 48e30bf42c2d..bafeb77c55e6 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -948,8 +948,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (Float.isNaN(brightnessState)) { float newAutoBrightnessAdjustment = autoBrightnessAdjustment; if (autoBrightnessEnabled) { - brightnessState = BrightnessSynchronizer.brightnessIntToFloat( - mContext, mAutomaticBrightnessController.getAutomaticScreenBrightness()); + brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness(); newAutoBrightnessAdjustment = mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment(); } diff --git a/services/core/java/com/android/server/display/HysteresisLevels.java b/services/core/java/com/android/server/display/HysteresisLevels.java index f0a505d4d818..2b565698ff8c 100644 --- a/services/core/java/com/android/server/display/HysteresisLevels.java +++ b/services/core/java/com/android/server/display/HysteresisLevels.java @@ -64,8 +64,8 @@ public class HysteresisLevels { * Return the brightening hysteresis threshold for the given value level. */ public float getBrighteningThreshold(float value) { - float brightConstant = getReferenceLevel(value, mBrighteningThresholds); - float brightThreshold = value * (1.0f + brightConstant); + final float brightConstant = getReferenceLevel(value, mBrighteningThresholds); + final float brightThreshold = value * (1.0f + brightConstant); if (DEBUG) { Slog.d(TAG, "bright hysteresis constant=" + brightConstant + ", threshold=" + brightThreshold + ", value=" + value); @@ -77,8 +77,8 @@ public class HysteresisLevels { * Return the darkening hysteresis threshold for the given value level. */ public float getDarkeningThreshold(float value) { - float darkConstant = getReferenceLevel(value, mDarkeningThresholds); - float darkThreshold = value * (1.0f - darkConstant); + final float darkConstant = getReferenceLevel(value, mDarkeningThresholds); + final float darkThreshold = value * (1.0f - darkConstant); if (DEBUG) { Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold=" + darkThreshold + ", value=" + value); diff --git a/services/core/java/com/android/server/emergency/EmergencyAffordanceService.java b/services/core/java/com/android/server/emergency/EmergencyAffordanceService.java index 1cf27ffd1903..cc7915cc3534 100644 --- a/services/core/java/com/android/server/emergency/EmergencyAffordanceService.java +++ b/services/core/java/com/android/server/emergency/EmergencyAffordanceService.java @@ -20,90 +20,80 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.provider.Settings; -import android.telephony.CellInfo; -import android.telephony.CellInfoGsm; -import android.telephony.CellInfoLte; -import android.telephony.CellInfoWcdma; -import android.telephony.CellLocation; -import android.telephony.PhoneStateListener; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.util.Slog; +import com.android.internal.util.DumpUtils; +import com.android.internal.util.IndentingPrintWriter; import com.android.server.SystemService; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** - * A service that listens to connectivity and SIM card changes and determines if the emergency mode - * should be enabled + * A service that listens to connectivity and SIM card changes and determines if the emergency + * affordance should be enabled. */ public class EmergencyAffordanceService extends SystemService { private static final String TAG = "EmergencyAffordanceService"; + private static final boolean DBG = false; - private static final int NUM_SCANS_UNTIL_ABORT = 4; + private static final String SERVICE_NAME = "emergency_affordance"; private static final int INITIALIZE_STATE = 1; - private static final int CELL_INFO_STATE_CHANGED = 2; - private static final int SUBSCRIPTION_CHANGED = 3; - /** - * Global setting, whether the last scan of the sim cards reveal that a sim was inserted that - * requires the emergency affordance. The value is a boolean (1 or 0). - * @hide + * @param arg1 slot Index + * @param arg2 0 + * @param obj ISO country code */ - private static final String EMERGENCY_SIM_INSERTED_SETTING = "emergency_sim_inserted_before"; - - private final Context mContext; - private final ArrayList<Integer> mEmergencyCallMccNumbers; + private static final int NETWORK_COUNTRY_CHANGED = 2; + private static final int SUBSCRIPTION_CHANGED = 3; + private static final int UPDATE_AIRPLANE_MODE_STATUS = 4; - private final Object mLock = new Object(); + // Global Settings to override emergency affordance country ISO for debugging. + // Available only on debug build. The value is a country ISO string in lower case (eg. "us"). + private static final String EMERGENCY_AFFORDANCE_OVERRIDE_ISO = + "emergency_affordance_override_iso"; - private TelephonyManager mTelephonyManager; + private final Context mContext; + // Country ISOs that require affordance + private final ArrayList<String> mEmergencyCallCountryIsos; private SubscriptionManager mSubscriptionManager; - private boolean mEmergencyAffordanceNeeded; + private TelephonyManager mTelephonyManager; private MyHandler mHandler; - private int mScansCompleted; - private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { - @Override - public void onCellInfoChanged(List<CellInfo> cellInfo) { - if (!isEmergencyAffordanceNeeded()) { - requestCellScan(); - } - } + private boolean mAnySimNeedsEmergencyAffordance; + private boolean mAnyNetworkNeedsEmergencyAffordance; + private boolean mEmergencyAffordanceNeeded; + private boolean mAirplaneModeEnabled; + private boolean mVoiceCapable; - @Override - public void onCellLocationChanged(CellLocation location) { - if (!isEmergencyAffordanceNeeded()) { - requestCellScan(); - } - } - }; - private BroadcastReceiver mAirplaneModeReceiver = new BroadcastReceiver() { + private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (Settings.Global.getInt(context.getContentResolver(), - Settings.Global.AIRPLANE_MODE_ON, 0) == 0) { - startScanning(); - requestCellScan(); + if (TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED.equals(intent.getAction())) { + String countryCode = intent.getStringExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY); + int slotId = intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX, + SubscriptionManager.INVALID_SIM_SLOT_INDEX); + mHandler.obtainMessage( + NETWORK_COUNTRY_CHANGED, slotId, 0, countryCode).sendToTarget(); + } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) { + mHandler.obtainMessage(UPDATE_AIRPLANE_MODE_STATUS).sendToTarget(); } } }; - private boolean mSimNeedsEmergencyAffordance; - private boolean mNetworkNeedsEmergencyAffordance; - private boolean mVoiceCapable; - - private void requestCellScan() { - mHandler.obtainMessage(CELL_INFO_STATE_CHANGED).sendToTarget(); - } private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener = new SubscriptionManager.OnSubscriptionsChangedListener() { @@ -116,207 +106,200 @@ public class EmergencyAffordanceService extends SystemService { public EmergencyAffordanceService(Context context) { super(context); mContext = context; - int[] numbers = context.getResources().getIntArray( - com.android.internal.R.array.config_emergency_mcc_codes); - mEmergencyCallMccNumbers = new ArrayList<>(numbers.length); - for (int i = 0; i < numbers.length; i++) { - mEmergencyCallMccNumbers.add(numbers[i]); + String[] isos = context.getResources().getStringArray( + com.android.internal.R.array.config_emergency_iso_country_codes); + mEmergencyCallCountryIsos = new ArrayList<>(isos.length); + for (String iso : isos) { + mEmergencyCallCountryIsos.add(iso); } - } - private void updateEmergencyAffordanceNeeded() { - synchronized (mLock) { - mEmergencyAffordanceNeeded = mVoiceCapable && (mSimNeedsEmergencyAffordance || - mNetworkNeedsEmergencyAffordance); - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.EMERGENCY_AFFORDANCE_NEEDED, - mEmergencyAffordanceNeeded ? 1 : 0); - if (mEmergencyAffordanceNeeded) { - stopScanning(); + if (Build.IS_DEBUGGABLE) { + String overrideIso = Settings.Global.getString( + mContext.getContentResolver(), EMERGENCY_AFFORDANCE_OVERRIDE_ISO); + if (!TextUtils.isEmpty(overrideIso)) { + if (DBG) Slog.d(TAG, "Override ISO to " + overrideIso); + mEmergencyCallCountryIsos.clear(); + mEmergencyCallCountryIsos.add(overrideIso); } } } - private void stopScanning() { - synchronized (mLock) { - mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); - mScansCompleted = 0; - } - } - - private boolean isEmergencyAffordanceNeeded() { - synchronized (mLock) { - return mEmergencyAffordanceNeeded; - } - } - @Override public void onStart() { + if (DBG) Slog.i(TAG, "onStart"); + publishBinderService(SERVICE_NAME, new BinderService()); } @Override public void onBootPhase(int phase) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { - mTelephonyManager = mContext.getSystemService(TelephonyManager.class); - mVoiceCapable = mTelephonyManager.isVoiceCapable(); - if (!mVoiceCapable) { - updateEmergencyAffordanceNeeded(); - return; - } - mSubscriptionManager = SubscriptionManager.from(mContext); - HandlerThread thread = new HandlerThread(TAG); - thread.start(); - mHandler = new MyHandler(thread.getLooper()); - mHandler.obtainMessage(INITIALIZE_STATE).sendToTarget(); - startScanning(); - IntentFilter filter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED); - mContext.registerReceiver(mAirplaneModeReceiver, filter); - mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener); + if (DBG) Slog.i(TAG, "onBootPhase"); + handleThirdPartyBootPhase(); } } - private void startScanning() { - mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CELL_INFO - | PhoneStateListener.LISTEN_CELL_LOCATION); - } - /** Handler to do the heavier work on */ private class MyHandler extends Handler { - public MyHandler(Looper l) { super(l); } @Override public void handleMessage(Message msg) { + if (DBG) Slog.d(TAG, "handleMessage: " + msg.what); switch (msg.what) { case INITIALIZE_STATE: handleInitializeState(); break; - case CELL_INFO_STATE_CHANGED: - handleUpdateCellInfo(); + case NETWORK_COUNTRY_CHANGED: + final String countryIso = (String) msg.obj; + final int slotId = msg.arg1; + handleNetworkCountryChanged(countryIso, slotId); break; case SUBSCRIPTION_CHANGED: handleUpdateSimSubscriptionInfo(); break; + case UPDATE_AIRPLANE_MODE_STATUS: + handleUpdateAirplaneModeStatus(); + break; + default: + Slog.e(TAG, "Unexpected message received: " + msg.what); } } } private void handleInitializeState() { - if (handleUpdateSimSubscriptionInfo()) { - return; - } - if (handleUpdateCellInfo()) { + if (DBG) Slog.d(TAG, "handleInitializeState"); + handleUpdateAirplaneModeStatus(); + handleUpdateSimSubscriptionInfo(); + updateNetworkCountry(); + updateEmergencyAffordanceNeeded(); + } + + private void handleThirdPartyBootPhase() { + if (DBG) Slog.d(TAG, "handleThirdPartyBootPhase"); + mTelephonyManager = mContext.getSystemService(TelephonyManager.class); + mVoiceCapable = mTelephonyManager.isVoiceCapable(); + if (!mVoiceCapable) { + updateEmergencyAffordanceNeeded(); return; } - updateEmergencyAffordanceNeeded(); + + HandlerThread thread = new HandlerThread(TAG); + thread.start(); + mHandler = new MyHandler(thread.getLooper()); + + mSubscriptionManager = SubscriptionManager.from(mContext); + mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener); + + IntentFilter filter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED); + filter.addAction(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED); + mContext.registerReceiver(mBroadcastReceiver, filter); + + mHandler.obtainMessage(INITIALIZE_STATE).sendToTarget(); + } + + private void handleUpdateAirplaneModeStatus() { + mAirplaneModeEnabled = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.AIRPLANE_MODE_ON, 0) == 1; + if (DBG) Slog.d(TAG, "APM status updated to " + mAirplaneModeEnabled); } - private boolean handleUpdateSimSubscriptionInfo() { - boolean neededBefore = simNeededAffordanceBefore(); - boolean neededNow = neededBefore; + private void handleUpdateSimSubscriptionInfo() { List<SubscriptionInfo> activeSubscriptionInfoList = mSubscriptionManager.getActiveSubscriptionInfoList(); + if (DBG) Slog.d(TAG, "handleUpdateSimSubscriptionInfo: " + activeSubscriptionInfoList); if (activeSubscriptionInfoList == null) { - setSimNeedsEmergencyAffordance(neededNow); - return neededNow; + return; } + + boolean needsAffordance = false; for (SubscriptionInfo info : activeSubscriptionInfoList) { - int mcc = info.getMcc(); - if (mccRequiresEmergencyAffordance(mcc)) { - neededNow = true; + if (isoRequiresEmergencyAffordance(info.getCountryIso())) { + needsAffordance = true; break; - } else if (mcc != 0 && mcc != Integer.MAX_VALUE){ - // a Sim with a different mcc code was found - neededNow = false; - } - String simOperator = mTelephonyManager - .createForSubscriptionId(info.getSubscriptionId()).getSimOperator(); - mcc = 0; - if (simOperator != null && simOperator.length() >= 3) { - mcc = Integer.parseInt(simOperator.substring(0, 3)); - } - if (mcc != 0) { - if (mccRequiresEmergencyAffordance(mcc)) { - neededNow = true; - break; - } else { - // a Sim with a different mcc code was found - neededNow = false; - } } } - setSimNeedsEmergencyAffordance(neededNow); - return neededNow; + + mAnySimNeedsEmergencyAffordance = needsAffordance; + updateEmergencyAffordanceNeeded(); } - private void setSimNeedsEmergencyAffordance(boolean simNeedsEmergencyAffordance) { - if (simNeededAffordanceBefore() != simNeedsEmergencyAffordance) { - Settings.Global.putInt(mContext.getContentResolver(), - EMERGENCY_SIM_INSERTED_SETTING, - simNeedsEmergencyAffordance ? 1 : 0); + private void handleNetworkCountryChanged(String countryIso, int slotId) { + if (DBG) { + Slog.d(TAG, "handleNetworkCountryChanged: countryIso=" + countryIso + + ", slotId=" + slotId); } - if (simNeedsEmergencyAffordance != mSimNeedsEmergencyAffordance) { - mSimNeedsEmergencyAffordance = simNeedsEmergencyAffordance; - updateEmergencyAffordanceNeeded(); + + if (TextUtils.isEmpty(countryIso) && mAirplaneModeEnabled) { + Slog.w(TAG, "Ignore empty countryIso report when APM is on."); + return; } - } - private boolean simNeededAffordanceBefore() { - return Settings.Global.getInt(mContext.getContentResolver(), - EMERGENCY_SIM_INSERTED_SETTING, 0) != 0; + updateNetworkCountry(); + + updateEmergencyAffordanceNeeded(); } - private boolean handleUpdateCellInfo() { - List<CellInfo> cellInfos = mTelephonyManager.getAllCellInfo(); - if (cellInfos == null) { - return false; - } - boolean stopScanningAfterScan = false; - for (CellInfo cellInfo : cellInfos) { - int mcc = 0; - if (cellInfo instanceof CellInfoGsm) { - mcc = ((CellInfoGsm) cellInfo).getCellIdentity().getMcc(); - } else if (cellInfo instanceof CellInfoLte) { - mcc = ((CellInfoLte) cellInfo).getCellIdentity().getMcc(); - } else if (cellInfo instanceof CellInfoWcdma) { - mcc = ((CellInfoWcdma) cellInfo).getCellIdentity().getMcc(); - } - if (mccRequiresEmergencyAffordance(mcc)) { - setNetworkNeedsEmergencyAffordance(true); - return true; - } else if (mcc != 0 && mcc != Integer.MAX_VALUE) { - // we found an mcc that isn't in the list, abort - stopScanningAfterScan = true; + private void updateNetworkCountry() { + boolean needsAffordance = false; + + final int activeModems = mTelephonyManager.getActiveModemCount(); + for (int i = 0; i < activeModems; i++) { + String countryIso = mTelephonyManager.getNetworkCountryIso(i); + if (DBG) Slog.d(TAG, "UpdateNetworkCountry: slotId=" + i + " countryIso=" + countryIso); + if (isoRequiresEmergencyAffordance(countryIso)) { + needsAffordance = true; + break; } } - if (stopScanningAfterScan) { - stopScanning(); - } else { - onCellScanFinishedUnsuccessful(); - } - setNetworkNeedsEmergencyAffordance(false); - return false; + + mAnyNetworkNeedsEmergencyAffordance = needsAffordance; + + updateEmergencyAffordanceNeeded(); } - private void setNetworkNeedsEmergencyAffordance(boolean needsAffordance) { - synchronized (mLock) { - mNetworkNeedsEmergencyAffordance = needsAffordance; - updateEmergencyAffordanceNeeded(); - } + private boolean isoRequiresEmergencyAffordance(String iso) { + return mEmergencyCallCountryIsos.contains(iso); } - private void onCellScanFinishedUnsuccessful() { - synchronized (mLock) { - mScansCompleted++; - if (mScansCompleted >= NUM_SCANS_UNTIL_ABORT) { - stopScanning(); - } + private void updateEmergencyAffordanceNeeded() { + if (DBG) { + Slog.d(TAG, "updateEmergencyAffordanceNeeded: mEmergencyAffordanceNeeded=" + + mEmergencyAffordanceNeeded + ", mVoiceCapable=" + mVoiceCapable + + ", mAnySimNeedsEmergencyAffordance=" + mAnySimNeedsEmergencyAffordance + + ", mAnyNetworkNeedsEmergencyAffordance=" + + mAnyNetworkNeedsEmergencyAffordance); + } + boolean lastAffordanceNeeded = mEmergencyAffordanceNeeded; + + mEmergencyAffordanceNeeded = mVoiceCapable + && (mAnySimNeedsEmergencyAffordance || mAnyNetworkNeedsEmergencyAffordance); + + if (lastAffordanceNeeded != mEmergencyAffordanceNeeded) { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.EMERGENCY_AFFORDANCE_NEEDED, + mEmergencyAffordanceNeeded ? 1 : 0); } } - private boolean mccRequiresEmergencyAffordance(int mcc) { - return mEmergencyCallMccNumbers.contains(mcc); + private void dumpInternal(IndentingPrintWriter ipw) { + ipw.println("EmergencyAffordanceService (dumpsys emergency_affordance) state:\n"); + ipw.println("mEmergencyAffordanceNeeded=" + mEmergencyAffordanceNeeded); + ipw.println("mVoiceCapable=" + mVoiceCapable); + ipw.println("mAnySimNeedsEmergencyAffordance=" + mAnySimNeedsEmergencyAffordance); + ipw.println("mAnyNetworkNeedsEmergencyAffordance=" + mAnyNetworkNeedsEmergencyAffordance); + ipw.println("mEmergencyCallCountryIsos=" + String.join(",", mEmergencyCallCountryIsos)); + } + + private final class BinderService extends Binder { + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) { + return; + } + + dumpInternal(new IndentingPrintWriter(pw, " ")); + } } } diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java index 44e973ecedfa..393e8db96c01 100644 --- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java +++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java @@ -117,6 +117,8 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { private static final String ALLOWED_INSTALLER_DELIMITER = ","; private static final String INSTALLER_PACKAGE_CERT_DELIMITER = "\\|"; + public static final boolean DEBUG_INTEGRITY_COMPONENT = false; + private static final Set<String> PACKAGE_INSTALLER = new HashSet<>( Arrays.asList( @@ -262,14 +264,18 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1); try { - Slog.i(TAG, "Received integrity verification intent " + intent.toString()); - Slog.i(TAG, "Extras " + intent.getExtras()); + if (DEBUG_INTEGRITY_COMPONENT) { + Slog.d(TAG, "Received integrity verification intent " + intent.toString()); + Slog.d(TAG, "Extras " + intent.getExtras()); + } String installerPackageName = getInstallerPackageName(intent); // Skip integrity verification if the verifier is doing the install. if (!integrityCheckIncludesRuleProvider() && isRuleProvider(installerPackageName)) { - Slog.i(TAG, "Verifier doing the install. Skipping integrity check."); + if (DEBUG_INTEGRITY_COMPONENT) { + Slog.i(TAG, "Verifier doing the install. Skipping integrity check."); + } mPackageManagerInternal.setIntegrityVerificationResult( verificationId, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW); return; @@ -303,19 +309,23 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { AppInstallMetadata appInstallMetadata = builder.build(); - Slog.i( - TAG, - "To be verified: " - + appInstallMetadata - + " installers " - + getAllowedInstallers(packageInfo)); + if (DEBUG_INTEGRITY_COMPONENT) { + Slog.i( + TAG, + "To be verified: " + + appInstallMetadata + + " installers " + + getAllowedInstallers(packageInfo)); + } IntegrityCheckResult result = mEvaluationEngine.evaluate(appInstallMetadata); - Slog.i( - TAG, - "Integrity check result: " - + result.getEffect() - + " due to " - + result.getMatchedRules()); + if (DEBUG_INTEGRITY_COMPONENT) { + Slog.i( + TAG, + "Integrity check result: " + + result.getEffect() + + " due to " + + result.getMatchedRules()); + } FrameworkStatsLog.write( FrameworkStatsLog.INTEGRITY_CHECK_RESULT_REPORTED, @@ -424,7 +434,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { .getPackageInfo(installer, PackageManager.GET_SIGNING_CERTIFICATES); return getCertificateFingerprint(installerInfo); } catch (PackageManager.NameNotFoundException e) { - Slog.i(TAG, "Installer package " + installer + " not found."); + Slog.w(TAG, "Installer package " + installer + " not found."); return Collections.emptyList(); } } @@ -653,28 +663,39 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { private String getCallingRulePusherPackageName(int callingUid) { // Obtain the system apps that are whitelisted in config_integrityRuleProviderPackages. List<String> allowedRuleProviders = getAllowedRuleProviderSystemApps(); - Slog.i(TAG, String.format( - "Rule provider system app list contains: %s", allowedRuleProviders)); + if (DEBUG_INTEGRITY_COMPONENT) { + Slog.i(TAG, String.format( + "Rule provider system app list contains: %s", allowedRuleProviders)); + } // Identify the package names in the caller list. List<String> callingPackageNames = getPackageListForUid(callingUid); - Slog.i(TAG, String.format("Calling packages are: ", callingPackageNames)); + if (DEBUG_INTEGRITY_COMPONENT) { + Slog.i(TAG, String.format("Calling packages are: ", callingPackageNames)); + } // Find the intersection between the allowed and calling packages. Ideally, we will have // at most one package name here. But if we have more, it is fine. - List<String> allowedCallingPackages = - callingPackageNames - .stream() - .filter(packageName -> allowedRuleProviders.contains(packageName)) - .collect(Collectors.toList()); - Slog.i(TAG, String.format("Calling rule pusher packages are: ", allowedCallingPackages)); - + List<String> allowedCallingPackages = new ArrayList<>(); + for (String packageName : callingPackageNames) { + if (allowedRuleProviders.contains(packageName)) { + allowedCallingPackages.add(packageName); + } + } + if (DEBUG_INTEGRITY_COMPONENT) { + Slog.i(TAG, + String.format("Calling rule pusher packages are: ", allowedCallingPackages)); + } return allowedCallingPackages.isEmpty() ? null : allowedCallingPackages.get(0); } private boolean isRuleProvider(String installerPackageName) { - return getAllowedRuleProviderSystemApps().stream() - .anyMatch(ruleProvider -> ruleProvider.equals(installerPackageName)); + for (String ruleProvider : getAllowedRuleProviderSystemApps()) { + if (ruleProvider.matches(installerPackageName)) { + return true; + } + } + return false; } private List<String> getAllowedRuleProviderSystemApps() { @@ -682,13 +703,18 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { Arrays.asList( mContext.getResources() .getStringArray(R.array.config_integrityRuleProviderPackages)); - - Slog.i(TAG, String.format("Rule provider list contains: %s", integrityRuleProviders)); + if (DEBUG_INTEGRITY_COMPONENT) { + Slog.i(TAG, String.format("Rule provider list contains: %s", integrityRuleProviders)); + } // Filter out the rule provider packages that are not system apps. - return integrityRuleProviders.stream() - .filter(this::isSystemApp) - .collect(Collectors.toList()); + List<String> systemAppRuleProviders = new ArrayList<>(); + for (String ruleProvider: integrityRuleProviders) { + if (isSystemApp(ruleProvider)) { + systemAppRuleProviders.add(ruleProvider); + } + } + return systemAppRuleProviders; } private boolean isSystemApp(String packageName) { diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java index bfc76df90cf3..e846daf7a2e6 100644 --- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java +++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java @@ -108,7 +108,9 @@ public class NotificationHistoryDatabase { public void init() { synchronized (mLock) { try { - mHistoryDir.mkdir(); + if (!mHistoryDir.mkdir()) { + throw new IllegalStateException("could not create history directory"); + } mVersionFile.createNewFile(); } catch (Exception e) { Slog.e(TAG, "could not create needed files", e); diff --git a/services/core/java/com/android/server/notification/NotificationHistoryManager.java b/services/core/java/com/android/server/notification/NotificationHistoryManager.java index f7fb9b71ec87..69a7ce90f1c6 100644 --- a/services/core/java/com/android/server/notification/NotificationHistoryManager.java +++ b/services/core/java/com/android/server/notification/NotificationHistoryManager.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.pm.UserInfo; import android.database.ContentObserver; import android.net.Uri; +import android.os.Binder; import android.os.Environment; import android.os.Handler; import android.os.UserHandle; @@ -37,6 +38,7 @@ import android.util.SparseBooleanArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.FunctionalUtils; import com.android.server.IoThread; import java.io.File; @@ -198,16 +200,18 @@ public class NotificationHistoryManager { } public void addNotification(@NonNull final HistoricalNotification notification) { - synchronized (mLock) { - final NotificationHistoryDatabase userHistory = - getUserHistoryAndInitializeIfNeededLocked(notification.getUserId()); - if (userHistory == null) { - Slog.w(TAG, "Attempted to add notif for locked/gone/disabled user " - + notification.getUserId()); - return; + Binder.withCleanCallingIdentity(() -> { + synchronized (mLock) { + final NotificationHistoryDatabase userHistory = + getUserHistoryAndInitializeIfNeededLocked(notification.getUserId()); + if (userHistory == null) { + Slog.w(TAG, "Attempted to add notif for locked/gone/disabled user " + + notification.getUserId()); + return; + } + userHistory.addNotification(notification); } - userHistory.addNotification(notification); - } + }); } public @NonNull NotificationHistory readNotificationHistory(@UserIdInt int[] userIds) { diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 8e9af1c63dc4..341e974bc82d 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -2718,6 +2718,16 @@ public class NotificationManagerService extends SystemService { } return text == null ? null : String.valueOf(text); } + + protected void maybeRegisterMessageSent(NotificationRecord r) { + Context appContext = r.getSbn().getPackageContext(getContext()); + Notification.Builder nb = + Notification.Builder.recoverBuilder(appContext, r.getNotification()); + if (nb.getStyle() instanceof Notification.MessagingStyle) { + mPreferencesHelper.setMessageSent(r.getSbn().getPackageName(), r.getUid()); + handleSavePolicyFile(); + } + } /** * Report to usage stats that the user interacted with the notification. @@ -3146,6 +3156,12 @@ public class NotificationManagerService extends SystemService { } @Override + public boolean hasSentMessage(String pkg, int uid) { + checkCallerIsSystem(); + return mPreferencesHelper.hasSentMessage(pkg, uid); + } + + @Override public void setNotificationDelegate(String callingPkg, String delegate) { checkCallerIsSameApp(callingPkg); final int callingUid = Binder.getCallingUid(); @@ -5683,6 +5699,14 @@ public class NotificationManagerService extends SystemService { return; } + if (info != null) { + // Cache the shortcut synchronously after the associated notification is posted in case + // the app unpublishes this shortcut immediately after posting the notification. If the + // user does not modify the notification settings on this conversation, the shortcut + // will be uncached by People Service when all the associated notifications are removed. + mShortcutHelper.cacheShortcut(info, user); + } + // Whitelist pending intents. if (notification.allPendingIntents != null) { final int intentCount = notification.allPendingIntents.size(); @@ -6459,6 +6483,7 @@ public class NotificationManagerService extends SystemService { } maybeRecordInterruptionLocked(r); + maybeRegisterMessageSent(r); // Log event to statsd mNotificationRecordLogger.maybeLogNotificationPosted(r, old, position, diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index d432fc83b52a..6d7b410b0b99 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -116,6 +116,7 @@ public class PreferencesHelper implements RankingConfig { private static final String ATT_ENABLED = "enabled"; private static final String ATT_USER_ALLOWED = "allowed"; private static final String ATT_HIDE_SILENT = "hide_gentle"; + private static final String ATT_SENT_MESSAGE = "sent_msg"; private static final int DEFAULT_PRIORITY = Notification.PRIORITY_DEFAULT; private static final int DEFAULT_VISIBILITY = NotificationManager.VISIBILITY_NO_OVERRIDE; @@ -269,6 +270,8 @@ public class PreferencesHelper implements RankingConfig { parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE); r.lockedAppFields = XmlUtils.readIntAttribute(parser, ATT_APP_USER_LOCKED_FIELDS, DEFAULT_LOCKED_APP_FIELDS); + r.hasSentMessage = XmlUtils.readBooleanAttribute( + parser, ATT_SENT_MESSAGE, false); final int innerDepth = parser.getDepth(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT @@ -510,7 +513,8 @@ public class PreferencesHelper implements RankingConfig { || r.channels.size() > 0 || r.groups.size() > 0 || r.delegate != null - || r.bubblePreference != DEFAULT_BUBBLE_PREFERENCE; + || r.bubblePreference != DEFAULT_BUBBLE_PREFERENCE + || r.hasSentMessage; if (hasNonDefaultSettings) { out.startTag(null, TAG_PACKAGE); out.attribute(null, ATT_NAME, r.pkg); @@ -529,6 +533,7 @@ public class PreferencesHelper implements RankingConfig { out.attribute(null, ATT_SHOW_BADGE, Boolean.toString(r.showBadge)); out.attribute(null, ATT_APP_USER_LOCKED_FIELDS, Integer.toString(r.lockedAppFields)); + out.attribute(null, ATT_SENT_MESSAGE, Boolean.toString(r.hasSentMessage)); if (!forBackup) { out.attribute(null, ATT_UID, Integer.toString(r.uid)); @@ -647,6 +652,18 @@ public class PreferencesHelper implements RankingConfig { updateConfig(); } + public boolean hasSentMessage(String packageName, int uid) { + synchronized (mPackagePreferences) { + return getOrCreatePackagePreferencesLocked(packageName, uid).hasSentMessage; + } + } + + public void setMessageSent(String packageName, int uid) { + synchronized (mPackagePreferences) { + getOrCreatePackagePreferencesLocked(packageName, uid).hasSentMessage = true; + } + } + @Override public boolean isGroupBlocked(String packageName, int uid, String groupId) { if (groupId == null) { @@ -819,7 +836,9 @@ public class PreferencesHelper implements RankingConfig { } if (fromTargetApp) { channel.setLockscreenVisibility(r.visibility); - channel.setAllowBubbles(existing != null && existing.canBubble()); + channel.setAllowBubbles(existing != null + ? existing.getAllowBubbles() + : NotificationChannel.DEFAULT_ALLOW_BUBBLE); } clearLockedFieldsLocked(channel); channel.setImportanceLockedByOEM(r.oemLockedImportance); @@ -1253,6 +1272,7 @@ public class PreferencesHelper implements RankingConfig { for (int i = 0; i < N; i++) { final NotificationChannel nc = p.channels.valueAt(i); if (!TextUtils.isEmpty(nc.getConversationId()) && !nc.isDeleted() + && !nc.isDemoted() && (nc.isImportantConversation() || !onlyImportant)) { ConversationChannelWrapper conversation = new ConversationChannelWrapper(); conversation.setPkg(p.pkg); @@ -1704,7 +1724,7 @@ public class PreferencesHelper implements RankingConfig { if (original.canShowBadge() != update.canShowBadge()) { update.lockFields(NotificationChannel.USER_LOCKED_SHOW_BADGE); } - if (original.canBubble() != update.canBubble()) { + if (original.getAllowBubbles() != update.getAllowBubbles()) { update.lockFields(NotificationChannel.USER_LOCKED_ALLOW_BUBBLE); } } @@ -2268,6 +2288,7 @@ public class PreferencesHelper implements RankingConfig { boolean oemLockedImportance = DEFAULT_OEM_LOCKED_IMPORTANCE; List<String> oemLockedChannels = new ArrayList<>(); boolean defaultAppLockedImportance = DEFAULT_APP_LOCKED_IMPORTANCE; + boolean hasSentMessage = false; Delegate delegate = null; ArrayMap<String, NotificationChannel> channels = new ArrayMap<>(); diff --git a/services/core/java/com/android/server/notification/ShortcutHelper.java b/services/core/java/com/android/server/notification/ShortcutHelper.java index 96da649350b0..13892ba0e480 100644 --- a/services/core/java/com/android/server/notification/ShortcutHelper.java +++ b/services/core/java/com/android/server/notification/ShortcutHelper.java @@ -34,6 +34,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -186,6 +187,17 @@ public class ShortcutHelper { } /** + * Caches the given shortcut in Shortcut Service. + */ + void cacheShortcut(ShortcutInfo shortcutInfo, UserHandle user) { + if (shortcutInfo.isLongLived() && !shortcutInfo.isCached()) { + mShortcutServiceInternal.cacheShortcuts(user.getIdentifier(), "android", + shortcutInfo.getPackage(), Collections.singletonList(shortcutInfo.getId()), + shortcutInfo.getUserId()); + } + } + + /** * Shortcut based bubbles require some extra work to listen for shortcut changes. * * @param r the notification record to check diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java index d36d038058f1..118fdcbcb736 100644 --- a/services/core/java/com/android/server/pm/AppsFilter.java +++ b/services/core/java/com/android/server/pm/AppsFilter.java @@ -27,12 +27,11 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.PackageParser; -import android.content.pm.parsing.component.ParsedActivity; import android.content.pm.parsing.component.ParsedComponent; import android.content.pm.parsing.component.ParsedInstrumentation; import android.content.pm.parsing.component.ParsedIntentInfo; +import android.content.pm.parsing.component.ParsedMainComponent; import android.content.pm.parsing.component.ParsedProvider; -import android.content.pm.parsing.component.ParsedService; import android.os.Binder; import android.os.Process; import android.os.Trace; @@ -302,7 +301,7 @@ public class AppsFilter { AndroidPackage potentialTarget, Set<String> protectedBroadcasts) { if (!querying.getQueriesIntents().isEmpty()) { for (Intent intent : querying.getQueriesIntents()) { - if (matchesIntentFilters(intent, potentialTarget, protectedBroadcasts)) { + if (matchesPackage(intent, potentialTarget, protectedBroadcasts)) { return true; } } @@ -354,33 +353,35 @@ public class AppsFilter { return false; } - private static boolean matchesIntentFilters(Intent intent, AndroidPackage potentialTarget, + private static boolean matchesPackage(Intent intent, AndroidPackage potentialTarget, Set<String> protectedBroadcasts) { - for (int s = ArrayUtils.size(potentialTarget.getServices()) - 1; s >= 0; s--) { - ParsedService service = potentialTarget.getServices().get(s); - if (!service.isExported()) { - continue; - } - if (matchesAnyFilter(intent, service, null /*protectedBroadcasts*/)) { - return true; - } + if (matchesAnyComponents( + intent, potentialTarget.getServices(), null /*protectedBroadcasts*/)) { + return true; } - for (int a = ArrayUtils.size(potentialTarget.getActivities()) - 1; a >= 0; a--) { - ParsedActivity activity = potentialTarget.getActivities().get(a); - if (!activity.isExported()) { - continue; - } - - if (matchesAnyFilter(intent, activity, null /*protectedBroadcasts*/)) { - return true; - } + if (matchesAnyComponents( + intent, potentialTarget.getActivities(), null /*protectedBroadcasts*/)) { + return true; + } + if (matchesAnyComponents(intent, potentialTarget.getReceivers(), protectedBroadcasts)) { + return true; + } + if (matchesAnyComponents( + intent, potentialTarget.getProviders(), null /*protectedBroadcasts*/)) { + return true; } - for (int r = ArrayUtils.size(potentialTarget.getReceivers()) - 1; r >= 0; r--) { - ParsedActivity receiver = potentialTarget.getReceivers().get(r); - if (!receiver.isExported()) { + return false; + } + + private static boolean matchesAnyComponents(Intent intent, + List<? extends ParsedMainComponent> components, + Set<String> protectedBroadcasts) { + for (int i = ArrayUtils.size(components) - 1; i >= 0; i--) { + ParsedMainComponent component = components.get(i); + if (!component.isExported()) { continue; } - if (matchesAnyFilter(intent, receiver, protectedBroadcasts)) { + if (matchesAnyFilter(intent, component, protectedBroadcasts)) { return true; } } diff --git a/services/core/java/com/android/server/pm/DataLoaderManagerService.java b/services/core/java/com/android/server/pm/DataLoaderManagerService.java index ae9c38498b10..dec3f1a86e01 100644 --- a/services/core/java/com/android/server/pm/DataLoaderManagerService.java +++ b/services/core/java/com/android/server/pm/DataLoaderManagerService.java @@ -23,7 +23,6 @@ import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; import android.content.pm.DataLoaderParamsParcel; -import android.content.pm.FileSystemControlParcel; import android.content.pm.IDataLoader; import android.content.pm.IDataLoaderManager; import android.content.pm.IDataLoaderStatusListener; @@ -35,7 +34,6 @@ import android.os.UserHandle; import android.util.Slog; import android.util.SparseArray; -import com.android.internal.annotations.GuardedBy; import com.android.server.SystemService; import java.util.List; @@ -49,8 +47,6 @@ public class DataLoaderManagerService extends SystemService { private static final String TAG = "DataLoaderManager"; private final Context mContext; private final DataLoaderManagerBinderService mBinderService; - private final Object mLock = new Object(); - @GuardedBy("mLock") private SparseArray<DataLoaderServiceConnection> mServiceConnections = new SparseArray<>(); public DataLoaderManagerService(Context context) { @@ -66,27 +62,30 @@ public class DataLoaderManagerService extends SystemService { final class DataLoaderManagerBinderService extends IDataLoaderManager.Stub { @Override - public boolean initializeDataLoader(int dataLoaderId, DataLoaderParamsParcel params, - FileSystemControlParcel control, IDataLoaderStatusListener listener) { - synchronized (mLock) { + public boolean bindToDataLoader(int dataLoaderId, DataLoaderParamsParcel params, + IDataLoaderStatusListener listener) { + synchronized (mServiceConnections) { if (mServiceConnections.get(dataLoaderId) != null) { - Slog.e(TAG, "Data loader of ID=" + dataLoaderId + " already exists."); - return false; + return true; } } ComponentName componentName = new ComponentName(params.packageName, params.className); ComponentName dataLoaderComponent = resolveDataLoaderComponentName(componentName); if (dataLoaderComponent == null) { + Slog.e(TAG, "Invalid component: " + componentName + " for ID=" + dataLoaderId); return false; } - // Binds to the specific data loader service - DataLoaderServiceConnection connection = - new DataLoaderServiceConnection(dataLoaderId, params, control, listener); + + // Binds to the specific data loader service. + DataLoaderServiceConnection connection = new DataLoaderServiceConnection(dataLoaderId, + listener); + Intent intent = new Intent(); intent.setComponent(dataLoaderComponent); if (!mContext.bindServiceAsUser(intent, connection, Context.BIND_AUTO_CREATE, UserHandle.of(UserHandle.getCallingUserId()))) { - Slog.e(TAG, "Failed to bind to data loader binder service."); + Slog.e(TAG, + "Failed to bind to: " + dataLoaderComponent + " for ID=" + dataLoaderId); mContext.unbindService(connection); return false; } @@ -146,7 +145,7 @@ public class DataLoaderManagerService extends SystemService { */ @Override public @Nullable IDataLoader getDataLoader(int dataLoaderId) { - synchronized (mLock) { + synchronized (mServiceConnections) { DataLoaderServiceConnection serviceConnection = mServiceConnections.get( dataLoaderId, null); if (serviceConnection == null) { @@ -157,14 +156,14 @@ public class DataLoaderManagerService extends SystemService { } /** - * Destroys a data loader binder service, specified by its ID. + * Unbinds from a data loader binder service, specified by its ID. DataLoader will receive + * destroy notification. */ @Override - public void destroyDataLoader(int dataLoaderId) { - synchronized (mLock) { + public void unbindFromDataLoader(int dataLoaderId) { + synchronized (mServiceConnections) { DataLoaderServiceConnection serviceConnection = mServiceConnections.get( dataLoaderId, null); - if (serviceConnection == null) { return; } @@ -173,18 +172,13 @@ public class DataLoaderManagerService extends SystemService { } } - class DataLoaderServiceConnection implements ServiceConnection { + private class DataLoaderServiceConnection implements ServiceConnection { final int mId; - final DataLoaderParamsParcel mParams; - final FileSystemControlParcel mControl; final IDataLoaderStatusListener mListener; IDataLoader mDataLoader; - DataLoaderServiceConnection(int id, DataLoaderParamsParcel params, - FileSystemControlParcel control, IDataLoaderStatusListener listener) { + DataLoaderServiceConnection(int id, IDataLoaderStatusListener listener) { mId = id; - mParams = params; - mControl = control; mListener = listener; mDataLoader = null; } @@ -192,25 +186,40 @@ public class DataLoaderManagerService extends SystemService { @Override public void onServiceConnected(ComponentName className, IBinder service) { mDataLoader = IDataLoader.Stub.asInterface(service); - synchronized (mLock) { - mServiceConnections.append(mId, this); + if (mDataLoader == null) { + onNullBinding(className); + return; } - try { - mDataLoader.create(mId, mParams, mControl, mListener); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to create data loader service.", e); + synchronized (mServiceConnections) { + if (mServiceConnections.get(mId) != null) { + // Another connection already bound for this ID. + mContext.unbindService(this); + return; + } + mServiceConnections.append(mId, this); } + callListener(IDataLoaderStatusListener.DATA_LOADER_BOUND); } @Override public void onServiceDisconnected(ComponentName arg0) { - if (mListener != null) { - try { - mListener.onStatusChanged(mId, IDataLoaderStatusListener.DATA_LOADER_DESTROYED); - } catch (RemoteException ignored) { - } - } - remove(); + Slog.i(TAG, "DataLoader " + mId + " disconnected, but will try to recover"); + callListener(IDataLoaderStatusListener.DATA_LOADER_DESTROYED); + destroy(); + } + + @Override + public void onBindingDied(ComponentName name) { + Slog.i(TAG, "DataLoader " + mId + " died"); + callListener(IDataLoaderStatusListener.DATA_LOADER_DESTROYED); + destroy(); + } + + @Override + public void onNullBinding(ComponentName name) { + Slog.i(TAG, "DataLoader " + mId + " failed to start"); + callListener(IDataLoaderStatusListener.DATA_LOADER_DESTROYED); + destroy(); } IDataLoader getDataLoader() { @@ -218,17 +227,30 @@ public class DataLoaderManagerService extends SystemService { } void destroy() { - try { - mDataLoader.destroy(mId); - } catch (RemoteException ignored) { + if (mDataLoader != null) { + try { + mDataLoader.destroy(mId); + } catch (RemoteException ignored) { + } + mDataLoader = null; } mContext.unbindService(this); + remove(); } private void remove() { - synchronized (mLock) { + synchronized (mServiceConnections) { mServiceConnections.remove(mId); } } + + private void callListener(int status) { + if (mListener != null) { + try { + mListener.onStatusChanged(mId, status); + } catch (RemoteException ignored) { + } + } + } } } diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 4cfd1ab73c9e..3367cd556b2b 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -979,6 +979,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements @Override public void bypassNextStagedInstallerCheck(boolean value) { + if (!isCalledBySystemOrShell(Binder.getCallingUid())) { + throw new SecurityException("Caller not allowed to bypass staged installer check"); + } mBypassNextStagedInstallerCheck = value; } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 6b1ef3acdf61..8e7eaf6e29fa 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -2601,8 +2601,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { "Failed to find data loader manager service"); } + final DataLoaderParams params = this.params.dataLoaderParams; final boolean manualStartAndDestroy = !isIncrementalInstallation(); - IDataLoaderStatusListener listener = new IDataLoaderStatusListener.Stub() { + final IDataLoaderStatusListener listener = new IDataLoaderStatusListener.Stub() { @Override public void onStatusChanged(int dataLoaderId, int status) { switch (status) { @@ -2629,6 +2630,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } switch (status) { + case IDataLoaderStatusListener.DATA_LOADER_BOUND: { + if (manualStartAndDestroy) { + FileSystemControlParcel control = new FileSystemControlParcel(); + control.callback = new FileSystemConnector(addedFiles); + dataLoader.create(dataLoaderId, params.getData(), control, this); + } + + break; + } case IDataLoaderStatusListener.DATA_LOADER_CREATED: { if (manualStartAndDestroy) { // IncrementalFileStorages will call start after all files are @@ -2680,8 +2690,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (!manualStartAndDestroy) { try { - mIncrementalFileStorages = IncrementalFileStorages.initialize(mContext, - stageDir, params.dataLoaderParams, listener, addedFiles); + mIncrementalFileStorages = IncrementalFileStorages.initialize(mContext, stageDir, + params, listener, addedFiles); return false; } catch (IOException e) { throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(), @@ -2689,13 +2699,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } - final FileSystemConnector connector = new FileSystemConnector(addedFiles); - final FileSystemControlParcel control = new FileSystemControlParcel(); - control.callback = connector; - - final DataLoaderParams params = this.params.dataLoaderParams; - if (!dataLoaderManager.initializeDataLoader( - sessionId, params.getData(), control, listener)) { + if (!dataLoaderManager.bindToDataLoader( + sessionId, params.getData(), listener)) { throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, "Failed to initialize data loader"); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 7adafe3ed658..28987ed8e7b3 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -11203,8 +11203,16 @@ public class PackageManagerService extends IPackageManager.Stub boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0; if (!needToDeriveAbi) { if (pkgSetting != null) { - primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString; - secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString; + // TODO(b/154610922): if it is not first boot or upgrade, we should directly use + // API info from existing package setting. However, stub packages currently do not + // preserve ABI info, thus the special condition check here. Remove the special + // check after we fix the stub generation. + if (pkgSetting.pkg != null && pkgSetting.pkg.isStub()) { + needToDeriveAbi = true; + } else { + primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString; + secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString; + } } else { // Re-scanning a system package after uninstalling updates; need to derive ABI needToDeriveAbi = true; @@ -20826,8 +20834,11 @@ public class PackageManagerService extends IPackageManager.Stub final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY; final SparseArray<int[]> broadcastWhitelist; synchronized (mLock) { - broadcastWhitelist = isInstantApp ? null : mAppsFilter.getVisibilityWhitelist( - getPackageSettingInternal(packageName, Process.SYSTEM_UID), + PackageSetting setting = getPackageSettingInternal(packageName, Process.SYSTEM_UID); + if (setting == null) { + return; + } + broadcastWhitelist = isInstantApp ? null : mAppsFilter.getVisibilityWhitelist(setting, userIds, mSettings.mPackages); } sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java index 2aa6e5737e9b..3614cc047bf8 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java @@ -217,7 +217,7 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService { case Metadata.LOCAL_FILE: { ParcelFileDescriptor incomingFd = null; try { - incomingFd = getLocalFile(shellCommand, metadata.getData()); + incomingFd = getLocalFilePFD(shellCommand, metadata.getData()); mConnector.writeData(file.getName(), 0, incomingFd.getStatSize(), incomingFd); } finally { @@ -263,10 +263,20 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService { } } - static ParcelFileDescriptor getLocalFile(ShellCommand shellCommand, String filePath) { + static ParcelFileDescriptor getLocalFilePFD(ShellCommand shellCommand, String filePath) { return shellCommand.openFileForSystem(filePath, "r"); } + static int getStdIn(ShellCommand shellCommand) { + ParcelFileDescriptor pfd = getStdInPFD(shellCommand); + return pfd == null ? -1 : pfd.detachFd(); + } + + static int getLocalFile(ShellCommand shellCommand, String filePath) { + ParcelFileDescriptor pfd = getLocalFilePFD(shellCommand, filePath); + return pfd == null ? -1 : pfd.detachFd(); + } + @Override public DataLoaderService.DataLoader onCreateDataLoader( @NonNull DataLoaderParams dataLoaderParams) { diff --git a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java index 780b2347287a..4a1a6a766726 100644 --- a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java +++ b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java @@ -31,6 +31,7 @@ import android.content.pm.parsing.component.ParsedActivity; import android.content.pm.parsing.component.ParsedInstrumentation; import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedService; +import android.os.incremental.IncrementalManager; import android.text.TextUtils; import com.android.internal.content.NativeLibraryHelper; @@ -141,8 +142,15 @@ public class AndroidPackageUtils { public static boolean canHaveOatDir(AndroidPackage pkg, boolean isUpdatedSystemApp) { // The following app types CANNOT have oat directory - // - non-updated system apps - return !pkg.isSystem() || isUpdatedSystemApp; + // - non-updated system apps, + // - incrementally installed apps. + if (pkg.isSystem() && !isUpdatedSystemApp) { + return false; + } + if (IncrementalManager.isIncrementalPath(pkg.getCodePath())) { + return false; + } + return true; } public static boolean hasComponentClassName(AndroidPackage pkg, String className) { diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index d89605a9ddbd..da07223686d7 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -395,14 +395,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { return false; } - /** - * Returns true if the window has a letterbox and any part of that letterbox overlaps with - * the given {@code rect}. - */ - default boolean isLetterboxedOverlappingWith(Rect rect) { - return false; - } - /** @return the current windowing mode of this window. */ int getWindowingMode(); diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java index 2256b623fce0..af14d84d12b8 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java @@ -838,7 +838,8 @@ public class BatterySaverStateMachine { Intent intent = new Intent(intentAction); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent batterySaverIntent = PendingIntent.getActivity( - mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT); + mContext, 0 /* requestCode */, intent, + PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); final String title = res.getString(titleId); final String summary = res.getString(summaryId); diff --git a/services/core/java/com/android/server/soundtrigger_middleware/OWNERS b/services/core/java/com/android/server/soundtrigger_middleware/OWNERS new file mode 100644 index 000000000000..e5d037003ac4 --- /dev/null +++ b/services/core/java/com/android/server/soundtrigger_middleware/OWNERS @@ -0,0 +1,2 @@ +ytai@google.com +elaurent@google.com diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 1afec9c18a7f..6fd7250b205c 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -98,6 +98,7 @@ import android.os.connectivity.WifiActivityEnergyInfo; import android.os.storage.DiskInfo; import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; +import android.provider.DeviceConfig; import android.provider.Settings; import android.stats.storage.StorageEnums; import android.telephony.ModemActivityInfo; @@ -204,6 +205,7 @@ public class StatsPullAtomService extends SystemService { private static final int CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES = 8; private static final int OP_FLAGS_PULLED = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXY; private static final String COMMON_PERMISSION_PREFIX = "android.permission."; + private static final String APP_OPS_TARGET_COLLECTION_SIZE = "app_ops_target_collection_size"; private final Object mNetworkStatsLock = new Object(); @GuardedBy("mNetworkStatsLock") @@ -2913,7 +2915,10 @@ public class StatsPullAtomService extends SystemService { HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); if (mAppOpsSamplingRate == 0) { - mAppOpsSamplingRate = constrain((5000 * 100) / estimateAppOpsSize(), 1, 100); + int appOpsTargetCollectionSize = DeviceConfig.getInt( + DeviceConfig.NAMESPACE_PERMISSIONS, APP_OPS_TARGET_COLLECTION_SIZE, 5000); + mAppOpsSamplingRate = constrain( + (appOpsTargetCollectionSize * 100) / estimateAppOpsSize(), 1, 100); } processHistoricalOps(histOps, atomTag, pulledData); } catch (Throwable t) { diff --git a/services/core/java/com/android/server/testharness/TestHarnessModeService.java b/services/core/java/com/android/server/testharness/TestHarnessModeService.java index 735a9e41a03b..531136976c81 100644 --- a/services/core/java/com/android/server/testharness/TestHarnessModeService.java +++ b/services/core/java/com/android/server/testharness/TestHarnessModeService.java @@ -25,6 +25,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.UserInfo; import android.debug.AdbManagerInternal; +import android.debug.AdbTransportType; import android.location.LocationManager; import android.os.BatteryManager; import android.os.Binder; @@ -164,6 +165,10 @@ public class TestHarnessModeService extends SystemService { // Stop ADB before we enable it, otherwise on userdebug/eng builds, the keys won't have // registered with adbd, and it will prompt the user to confirm the keys. Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 0); + AdbManagerInternal adbManager = LocalServices.getService(AdbManagerInternal.class); + if (adbManager.isAdbEnabled(AdbTransportType.USB)) { + adbManager.stopAdbdForTransport(AdbTransportType.USB); + } // Disable the TTL for ADB keys before enabling ADB Settings.Global.putLong(cr, Settings.Global.ADB_ALLOWED_CONNECTION_TIME, 0); diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index abccf99579b7..785ca908b703 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -45,6 +45,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.util.ArraySet; +import android.util.IntArray; import android.util.Slog; import android.util.SparseArray; import android.util.TypedValue; @@ -66,6 +67,7 @@ import com.android.server.policy.WindowManagerPolicy; import com.android.server.wm.WindowManagerInternal.MagnificationCallbacks; import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallback; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -127,14 +129,13 @@ final class AccessibilityController { */ public boolean setWindowsForAccessibilityCallbackLocked(int displayId, WindowsForAccessibilityCallback callback) { - if (callback != null) { - final DisplayContent dc = mService.mRoot.getDisplayContentOrCreate(displayId); - if (dc == null) { - return false; - } + final DisplayContent dc = mService.mRoot.getDisplayContentOrCreate(displayId); + if (dc == null) { + return false; + } - final Display display = dc.getDisplay(); - if (display.getType() == Display.TYPE_VIRTUAL && dc.getParentWindow() != null) { + if (callback != null) { + if (isEmbeddedDisplay(dc)) { // If this display is an embedded one, its window observer should have been set from // window manager after setting its parent window. But if its window observer is // empty, that means this mapping didn't be set, and needs to do this again. @@ -151,13 +152,22 @@ final class AccessibilityController { mWindowsForAccessibilityObserver.put(displayId, new WindowsForAccessibilityObserver(mService, displayId, callback)); } else { + if (isEmbeddedDisplay(dc)) { + // If this display is an embedded one, its window observer should be removed along + // with the window observer of its parent display removed because the window + // observer of the embedded display and its parent display is the same, and would + // be removed together when stopping the window tracking of its parent display. So + // here don't need to do removing window observer of the embedded display again. + return true; + } final WindowsForAccessibilityObserver windowsForA11yObserver = mWindowsForAccessibilityObserver.get(displayId); - if (windowsForA11yObserver == null) { + if (windowsForA11yObserver == null) { throw new IllegalStateException( "Windows for accessibility callback of display " + displayId + " already cleared!"); } + removeObserverOfEmbeddedDisplay(windowsForA11yObserver); mWindowsForAccessibilityObserver.remove(displayId); } return true; @@ -331,6 +341,7 @@ final class AccessibilityController { mWindowsForAccessibilityObserver.get(parentDisplayId); if (windowsForA11yObserver != null) { + windowsForA11yObserver.addEmbeddedDisplay(embeddedDisplayId); // Replaces the observer of embedded display to the one of parent display mWindowsForAccessibilityObserver.put(embeddedDisplayId, windowsForA11yObserver); } @@ -341,6 +352,33 @@ final class AccessibilityController { windowState.getTransformationMatrix(sTempFloats, outMatrix); } + void dump(PrintWriter pw, String prefix) { + for (int i = 0; i < mDisplayMagnifiers.size(); i++) { + final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.valueAt(i); + if (displayMagnifier != null) { + displayMagnifier.dump(pw, prefix + + "Magnification display# " + mDisplayMagnifiers.keyAt(i)); + } + } + } + + private void removeObserverOfEmbeddedDisplay(WindowsForAccessibilityObserver + observerOfParentDisplay) { + final IntArray embeddedDisplayIdList = + observerOfParentDisplay.getAndClearEmbeddedDisplayIdList(); + + for (int index = 0; index < embeddedDisplayIdList.size(); index++) { + final int embeddedDisplayId = embeddedDisplayIdList.get(index); + mWindowsForAccessibilityObserver.remove(embeddedDisplayId); + } + } + + private static boolean isEmbeddedDisplay(DisplayContent dc) { + final Display display = dc.getDisplay(); + + return display.getType() == Display.TYPE_VIRTUAL && dc.getParentWindow() != null; + } + /** * This class encapsulates the functionality related to display magnification. */ @@ -551,6 +589,10 @@ final class AccessibilityController { mMagnifedViewport.drawWindowIfNeededLocked(t); } + void dump(PrintWriter pw, String prefix) { + mMagnifedViewport.dump(pw, prefix); + } + private final class MagnifiedViewport { private final SparseArray<WindowState> mTempWindowStates = @@ -820,6 +862,10 @@ final class AccessibilityController { }, false /* traverseTopToBottom */ ); } + void dump(PrintWriter pw, String prefix) { + mWindow.dump(pw, prefix); + } + private final class ViewportWindow { private static final String SURFACE_TITLE = "Magnification Overlay"; @@ -985,6 +1031,14 @@ final class AccessibilityController { mSurface.release(); } + void dump(PrintWriter pw, String prefix) { + pw.println(prefix + + " mBounds= " + mBounds + + " mDirtyRect= " + mDirtyRect + + " mWidth= " + mSurfaceControl.getWidth() + + " mHeight= " + mSurfaceControl.getHeight()); + } + private final class AnimationController extends Handler { private static final String PROPERTY_NAME_ALPHA = "alpha"; @@ -1152,6 +1206,8 @@ final class AccessibilityController { private final long mRecurringAccessibilityEventsIntervalMillis; + private final IntArray mEmbeddedDisplayIdList = new IntArray(0); + public WindowsForAccessibilityObserver(WindowManagerService windowManagerService, int displayId, WindowsForAccessibilityCallback callback) { @@ -1176,6 +1232,21 @@ final class AccessibilityController { } } + IntArray getAndClearEmbeddedDisplayIdList() { + final IntArray returnedArray = new IntArray(mEmbeddedDisplayIdList.size()); + returnedArray.addAll(mEmbeddedDisplayIdList); + mEmbeddedDisplayIdList.clear(); + + return returnedArray; + } + + void addEmbeddedDisplay(int displayId) { + if (displayId == mDisplayId) { + return; + } + mEmbeddedDisplayIdList.add(displayId); + } + /** * Check if windows have changed, and send them to the accessibility subsystem if they have. * diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 2648c86d3c6a..130da2dfe9c5 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1188,12 +1188,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null; if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) { - // Picture-in-picture mode changes also trigger a multi-window mode change as well, so - // update that here in order. Set the last reported MW state to the same as the PiP - // state since we haven't yet actually resized the task (these callbacks need to - // preceed the configuration change from the resiez. + // Picture-in-picture mode change normal triggers also multi-window mode change + // except transitions between pip and split screen mode, so update that here in order. + // Set the last reported MW state to the same as the PiP state since we haven't yet + // actually resized the task (these callbacks need to proceed the configuration change + // from the resize). // TODO(110009072): Once we move these callbacks to the client, remove all logic related // to forcing the update of the picture-in-picture mode as a part of the PiP animation. + final boolean shouldScheduleMultiWindowModeChange = + mLastReportedMultiWindowMode != inMultiWindowMode(); mLastReportedPictureInPictureMode = inPictureInPictureMode; mLastReportedMultiWindowMode = inPictureInPictureMode; final Configuration newConfig = new Configuration(); @@ -1204,7 +1207,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A task.computeConfigResourceOverrides(newConfig, task.getParent().getConfiguration()); } schedulePictureInPictureModeChanged(newConfig); - scheduleMultiWindowModeChanged(newConfig); + if (shouldScheduleMultiWindowModeChange) { + scheduleMultiWindowModeChanged(newConfig); + } } } @@ -1414,11 +1419,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } /** - * @return {@code true} if there is a letterbox and any part of that letterbox overlaps with - * the given {@code rect}. + * @see Letterbox#notIntersectsOrFullyContains(Rect) */ - boolean isLetterboxOverlappingWith(Rect rect) { - return mLetterbox != null && mLetterbox.isOverlappingWith(rect); + boolean letterboxNotIntersectsOrFullyContains(Rect rect) { + return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect); } static class Token extends IApplicationToken.Stub { @@ -2672,7 +2676,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (isState(PAUSED) && mStackSupervisor.getKeyguardController().isKeyguardLocked() && getStack().topActivityOccludesKeyguard()) { - getStack().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, + getDisplay().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, false /* preserveWindows */, false /* notifyClients */); } @@ -3137,7 +3141,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A commitVisibility(false /* visible */, true /* performLayout */); getDisplayContent().mOpeningApps.remove(this); - getDisplayContent().mChangingContainers.remove(this); getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this); mWmService.mTaskSnapshotController.onAppRemoved(this); mStackSupervisor.getActivityMetricsLogger().notifyActivityRemoved(this); @@ -6130,19 +6133,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @Override void cancelAnimation() { - cancelAnimationOnly(); - clearThumbnail(); - mSurfaceFreezer.unfreeze(getPendingTransaction()); - } - - /** - * This only cancels the animation. It doesn't do other teardown like cleaning-up thumbnail - * or interim leashes. - * <p> - * Used when canceling in preparation for starting a new animation. - */ - void cancelAnimationOnly() { super.cancelAnimation(); + clearThumbnail(); } @VisibleForTesting diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index ff43e77a5c47..2ab03ce058b2 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -3264,7 +3264,15 @@ class ActivityStack extends Task { } boolean shouldIgnoreInput() { - return inSplitScreenPrimaryWindowingMode() && !isFocusable(); + if (inSplitScreenPrimaryWindowingMode() && !isFocusable()) { + return true; + } + if (mAtmService.mHasLeanbackFeature && inPinnedWindowingMode() + && !isFocusedStackOnDisplay()) { + // Preventing Picture-in-Picture stack from receiving input on TVs. + return true; + } + return false; } @Override diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 0754a348740b..8edc84fc8f37 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -168,7 +168,6 @@ class ActivityStarter { // The task display area to launch the activity onto, barring any strong reason to do otherwise. private TaskDisplayArea mPreferredTaskDisplayArea; - // The windowing mode to apply to the root task, if possible private int mPreferredWindowingMode; private Task mInTask; @@ -1560,9 +1559,6 @@ class ActivityStarter { if (!mAvoidMoveToFront && mDoResume) { mTargetStack.getStack().moveToFront("reuseOrNewTask", targetTask); if (mOptions != null) { - if (mPreferredWindowingMode != WINDOWING_MODE_UNDEFINED) { - mTargetStack.setWindowingMode(mPreferredWindowingMode); - } if (mOptions.getTaskAlwaysOnTop()) { mTargetStack.setAlwaysOnTop(true); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 93a757449564..5220fb25af74 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -42,7 +42,9 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST; import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED; import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS; +import static android.content.pm.PackageManager.FEATURE_CANT_SAVE_STATE; import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; +import static android.content.pm.PackageManager.FEATURE_LEANBACK; import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL; @@ -393,6 +395,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** The currently running heavy-weight process, if any. */ WindowProcessController mHeavyWeightProcess = null; boolean mHasHeavyWeightFeature; + boolean mHasLeanbackFeature; /** * This is the process holding the activity the user last visited that is in a different process * from the one they are currently in. @@ -734,8 +737,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public void onSystemReady() { synchronized (mGlobalLock) { - mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_CANT_SAVE_STATE); + final PackageManager pm = mContext.getPackageManager(); + mHasHeavyWeightFeature = pm.hasSystemFeature(FEATURE_CANT_SAVE_STATE); + mHasLeanbackFeature = pm.hasSystemFeature(FEATURE_LEANBACK); mAssistUtils = new AssistUtils(mContext); mVrController.onSystemReady(); mRecentTasks.onSystemReadyLocked(); @@ -6604,7 +6608,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } return; } - process.mIsImeProcess = true; process.registerDisplayConfigurationListener(displayContent); } } diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java index 57cdb0b77bdb..8b14095874e3 100644 --- a/services/core/java/com/android/server/wm/BarController.java +++ b/services/core/java/com/android/server/wm/BarController.java @@ -168,7 +168,7 @@ public class BarController { } boolean isTransparentAllowed(WindowState win) { - return win == null || !win.isLetterboxedOverlappingWith(mContentFrame); + return win == null || win.letterboxNotIntersectsOrFullyContains(mContentFrame); } boolean setBarShowingLw(final boolean show) { diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index a512337c96ec..9b34bd17d042 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -31,8 +31,10 @@ import static com.android.server.wm.DisplayAreaProto.WINDOW_CONTAINER; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.server.wm.WindowContainerChildProto.DISPLAY_AREA; +import android.content.res.Configuration; import android.graphics.Rect; import android.util.proto.ProtoOutputStream; +import android.window.DisplayAreaInfo; import android.window.IDisplayAreaOrganizer; import com.android.server.policy.WindowManagerPolicy; @@ -154,10 +156,26 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { } @Override + public void onConfigurationChanged(Configuration newParentConfig) { + super.onConfigurationChanged(newParentConfig); + if (mOrganizer != null) { + mOrganizerController.onDisplayAreaInfoChanged(mOrganizer, this); + } + } + + @Override boolean isOrganized() { return mOrganizer != null; } + + DisplayAreaInfo getDisplayAreaInfo() { + DisplayAreaInfo info = new DisplayAreaInfo(mRemoteToken.toWindowContainerToken(), + getDisplayContent().getDisplayId()); + info.configuration.setTo(getConfiguration()); + return info; + } + /** * DisplayArea that contains WindowTokens, and orders them according to their type. */ diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java index f05783b8f3ef..2c8c8201c534 100644 --- a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java +++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java @@ -92,9 +92,28 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl } } + @Override + public void unregisterOrganizer(IDisplayAreaOrganizer organizer) { + enforceStackPermission("unregisterTaskOrganizer()"); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + mOrganizersByFeatureIds.entrySet().removeIf( + entry -> entry.getValue().asBinder() == organizer.asBinder()); + + mService.mRootWindowContainer.forAllDisplayAreas((da) -> { + if (da.mOrganizer != organizer) return; + da.setOrganizer(null); + }); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + void onDisplayAreaAppeared(IDisplayAreaOrganizer organizer, DisplayArea da) { try { - organizer.onDisplayAreaAppeared(da.mRemoteToken.toWindowContainerToken()); + organizer.onDisplayAreaAppeared(da.getDisplayAreaInfo()); } catch (RemoteException e) { // Oh well... } @@ -102,7 +121,15 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl void onDisplayAreaVanished(IDisplayAreaOrganizer organizer, DisplayArea da) { try { - organizer.onDisplayAreaVanished(da.mRemoteToken.toWindowContainerToken()); + organizer.onDisplayAreaVanished(da.getDisplayAreaInfo()); + } catch (RemoteException e) { + // Oh well... + } + } + + void onDisplayAreaInfoChanged(IDisplayAreaOrganizer organizer, DisplayArea da) { + try { + organizer.onDisplayAreaInfoChanged(da.getDisplayAreaInfo()); } catch (RemoteException e) { // Oh well... } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index e26163247020..8f7fc9e354a0 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5534,4 +5534,34 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } } + + /** + * Returns the number of window tokens without surface on this display. A {@link WindowToken} + * won't have its {@link SurfaceControl} until a window is added to a {@link WindowToken}. + * The purpose of this method is to accumulate non-window containing {@link WindowToken}s and + * limit the usage if the count exceeds a number. + * + * @param callingUid app calling uid + * @return the number of window tokens without surface on this display + * @see WindowToken#addWindow(WindowState) + */ + int getWindowTokensWithoutSurfaceCount(int callingUid) { + List<WindowToken> tokens = new ArrayList<>(mTokenMap.values()); + int count = 0; + for (int i = tokens.size() - 1; i >= 0; i--) { + final WindowToken token = tokens.get(i); + if (callingUid != token.getOwnerUid()) { + continue; + } + // Skip if token is an Activity + if (token.asActivityRecord() != null) { + continue; + } + if (token.mSurfaceControl != null) { + continue; + } + count++; + } + return count; + } } diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 61a199a816df..5a9bf809fa4a 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -126,13 +126,22 @@ class InsetsPolicy { mPolicy.getStatusBarManagerInternal().showTransient(mDisplayContent.getDisplayId(), mShowingTransientTypes.toArray()); updateBarControlTarget(mFocusedWin); - InsetsState state = new InsetsState(mStateController.getRawInsetsState()); - startAnimation(true /* show */, () -> { + + // The leashes can be created while updating bar control target. The surface transaction + // of the new leashes might not be applied yet. The callback posted here ensures we can + // get the valid leashes because the surface transaction will be applied in the next + // animation frame which will be triggered if a new leash is created. + mDisplayContent.mWmService.mAnimator.getChoreographer().postFrameCallback(time -> { synchronized (mDisplayContent.mWmService.mGlobalLock) { - mStateController.notifyInsetsChanged(); + final InsetsState state = new InsetsState(mStateController.getRawInsetsState()); + startAnimation(true /* show */, () -> { + synchronized (mDisplayContent.mWmService.mGlobalLock) { + mStateController.notifyInsetsChanged(); + } + }, state); + mStateController.onInsetsModified(mDummyControlTarget, state); } - }, state); - mStateController.onInsetsModified(mDummyControlTarget, state); + }); } } diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 1ca82ceeb570..351743f962b9 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -66,6 +66,7 @@ class InsetsSourceProvider { private TriConsumer<DisplayFrames, WindowState, Rect> mFrameProvider; private TriConsumer<DisplayFrames, WindowState, Rect> mImeFrameProvider; private final Rect mImeOverrideFrame = new Rect(); + private boolean mIsLeashReadyForDispatching; /** The visibility override from the current controlling window. */ private boolean mClientVisible; @@ -266,9 +267,14 @@ class InsetsSourceProvider { if (getSource().getType() == ITYPE_IME) { setClientVisible(InsetsState.getDefaultVisibility(mSource.getType())); } - final Transaction t = mDisplayContent.mWmService.mTransactionFactory.get(); + final Transaction t = mDisplayContent.getPendingTransaction(); mWin.startAnimation(t, mAdapter, !mClientVisible /* hidden */, ANIMATION_TYPE_INSETS_CONTROL, null /* animationFinishedCallback */); + + // The leash was just created. We cannot dispatch it until its surface transaction is + // applied. Otherwise, the client's operation to the leash might be overwritten by us. + mIsLeashReadyForDispatching = false; + final SurfaceControl leash = mAdapter.mCapturedLeash; final long frameNumber = mFinishSeamlessRotateFrameNumber; mFinishSeamlessRotateFrameNumber = -1; @@ -281,9 +287,6 @@ class InsetsSourceProvider { t.deferTransactionUntil(mWin.getSurfaceControl(), barrier, frameNumber); t.deferTransactionUntil(leash, barrier, frameNumber); } - // Applying the transaction here can prevent the client from applying its transaction sooner - // than us which makes us overwrite the client's operation to the leash. - t.apply(); mControlTarget = target; mControl = new InsetsSourceControl(mSource.getType(), leash, new Point(mWin.getWindowFrames().mFrame.left, mWin.getWindowFrames().mFrame.top)); @@ -313,6 +316,10 @@ class InsetsSourceProvider { return true; } + void onSurfaceTransactionApplied() { + mIsLeashReadyForDispatching = true; + } + private void setClientVisible(boolean clientVisible) { if (mClientVisible == clientVisible) { return; @@ -334,6 +341,13 @@ class InsetsSourceProvider { InsetsSourceControl getControl(InsetsControlTarget target) { if (target == mControlTarget) { + if (!mIsLeashReadyForDispatching && mControl != null) { + // The surface transaction of preparing leash is not applied yet. We don't send it + // to the client in case that the client applies its transaction sooner than ours + // that we could unexpectedly overwrite the surface state. + return new InsetsSourceControl(mControl.getType(), null /* leash */, + mControl.getSurfacePosition()); + } return mControl; } if (target == mFakeControlTarget) { diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index 4ac319ddf6ce..765f98065dd0 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -407,6 +407,10 @@ class InsetsStateController { return; } mDisplayContent.mWmService.mAnimator.addAfterPrepareSurfacesRunnable(() -> { + for (int i = mProviders.size() - 1; i >= 0; i--) { + final InsetsSourceProvider provider = mProviders.valueAt(i); + provider.onSurfaceTransactionApplied(); + } for (int i = mPendingControlChanged.size() - 1; i >= 0; i--) { final InsetsControlTarget controlTarget = mPendingControlChanged.valueAt(i); controlTarget.notifyInsetsControlChanged(); diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java index 6721ef836e4e..00a4be3d1e35 100644 --- a/services/core/java/com/android/server/wm/Letterbox.java +++ b/services/core/java/com/android/server/wm/Letterbox.java @@ -77,10 +77,10 @@ public class Letterbox { mOuter.set(outer); mInner.set(inner); - mTop.layout(outer.left, outer.top, inner.right, inner.top, surfaceOrigin); - mLeft.layout(outer.left, inner.top, inner.left, outer.bottom, surfaceOrigin); - mBottom.layout(inner.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin); - mRight.layout(inner.right, outer.top, outer.right, inner.bottom, surfaceOrigin); + mTop.layout(outer.left, outer.top, outer.right, inner.top, surfaceOrigin); + mLeft.layout(outer.left, outer.top, inner.left, outer.bottom, surfaceOrigin); + mBottom.layout(outer.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin); + mRight.layout(inner.right, outer.top, outer.right, outer.bottom, surfaceOrigin); } @@ -101,17 +101,29 @@ public class Letterbox { } /** - * Returns true if any part of the letterbox overlaps with the given {@code rect}. + * Returns {@code true} if the letterbox does not overlap with the bar, or the letterbox can + * fully cover the window frame. + * + * @param rect The area of the window frame. */ - public boolean isOverlappingWith(Rect rect) { + boolean notIntersectsOrFullyContains(Rect rect) { + int emptyCount = 0; + int noOverlappingCount = 0; for (LetterboxSurface surface : mSurfaces) { - if (surface.isOverlappingWith(rect)) { + final Rect surfaceRect = surface.mLayoutFrameGlobal; + if (surfaceRect.isEmpty()) { + // empty letterbox + emptyCount++; + } else if (!Rect.intersects(surfaceRect, rect)) { + // no overlapping + noOverlappingCount++; + } else if (surfaceRect.contains(rect)) { + // overlapping and covered return true; } } - return false; + return (emptyCount + noOverlappingCount) == mSurfaces.length; } - /** * Hides the letterbox. * @@ -282,17 +294,6 @@ public class Letterbox { return Math.max(0, mLayoutFrameGlobal.height()); } - /** - * Returns if the given {@code rect} overlaps with this letterbox piece. - * @param rect the area to check for overlap in global coordinates - */ - public boolean isOverlappingWith(Rect rect) { - if (mLayoutFrameGlobal.isEmpty()) { - return false; - } - return Rect.intersects(rect, mLayoutFrameGlobal); - } - public void applySurfaceChanges(SurfaceControl.Transaction t) { if (mSurfaceFrameRelative.equals(mLayoutFrameRelative)) { // Nothing changed. diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 7bdd9c986c0e..77841dc2c0bf 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -42,6 +42,7 @@ import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; +import static com.android.server.wm.ActivityStack.ActivityState.FINISHING; import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; @@ -3324,7 +3325,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); final ActivityRecord r = stack.mPausingActivity; - if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) { + if (r != null && !r.isState(PAUSED, STOPPED, STOPPING, FINISHING)) { if (DEBUG_STATES) { Slog.d(TAG_STATES, "allPausedActivitiesComplete: r=" + r + " state=" + r.getState()); diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index 9d44cad70281..86e081854597 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -212,7 +212,7 @@ class ScreenRotationAnimation { final Surface surface = mService.mSurfaceFactory.get(); surface.copyFrom(mScreenshotLayer); SurfaceControl.ScreenshotGraphicBuffer gb = - mService.mDisplayManagerInternal.screenshot(displayId); + mService.mDisplayManagerInternal.systemScreenshot(displayId); if (gb != null) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "ScreenRotationAnimation#getMedianBorderLuma"); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index df5cfee6c01c..93c6b6e7b83c 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -1943,12 +1943,15 @@ class Task extends WindowContainer<WindowContainer> { final int prevWinMode = getWindowingMode(); mTmpPrevBounds.set(getBounds()); final boolean wasInMultiWindowMode = inMultiWindowMode(); + final boolean wasInPictureInPicture = inPinnedWindowingMode(); super.onConfigurationChanged(newParentConfig); // Only need to update surface size here since the super method will handle updating // surface position. updateSurfaceSize(getPendingTransaction()); - if (wasInMultiWindowMode != inMultiWindowMode()) { + if (wasInPictureInPicture != inPinnedWindowingMode()) { + mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, getStack()); + } else if (wasInMultiWindowMode != inMultiWindowMode()) { mStackSupervisor.scheduleUpdateMultiWindowMode(this); } @@ -1992,7 +1995,8 @@ class Task extends WindowContainer<WindowContainer> { if (mWmService.mDisableTransitionAnimation || !isVisible() || getDisplayContent().mAppTransition.isTransitionSet() - || getSurfaceControl() == null) { + || getSurfaceControl() == null + || !isLeafTask()) { return false; } // Only do an animation into and out-of freeform mode for now. Other mode @@ -2281,16 +2285,18 @@ class Task extends WindowContainer<WindowContainer> { } density *= DisplayMetrics.DENSITY_DEFAULT_SCALE; - // If bounds have been overridden at this level, restrict config resources to these bounds - // rather than the parent because the overridden bounds can be larger than the parent. - boolean hasOverrideBounds = false; + // The bounds may have been overridden at this level. If the parent cannot cover these + // bounds, the configuration is still computed according to the override bounds. + final boolean insideParentBounds; + final Rect parentBounds = parentConfig.windowConfiguration.getBounds(); final Rect resolvedBounds = inOutConfig.windowConfiguration.getBounds(); if (resolvedBounds == null || resolvedBounds.isEmpty()) { - mTmpFullBounds.set(parentConfig.windowConfiguration.getBounds()); + mTmpFullBounds.set(parentBounds); + insideParentBounds = true; } else { mTmpFullBounds.set(resolvedBounds); - hasOverrideBounds = true; + insideParentBounds = parentBounds.contains(resolvedBounds); } Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); @@ -2299,30 +2305,30 @@ class Task extends WindowContainer<WindowContainer> { outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); } // Non-null compatibility insets means the activity prefers to keep its original size, so - // the out bounds doesn't need to be restricted by the parent. - final boolean insideParentBounds = compatInsets == null; - if (insideParentBounds && windowingMode != WINDOWING_MODE_FREEFORM) { - Rect parentAppBounds; - if (hasOverrideBounds) { - // Since we overrode the bounds, restrict appBounds to display non-decor rather - // than parent. Otherwise, it won't match the overridden bounds. - final TaskDisplayArea displayArea = getDisplayArea(); - parentAppBounds = displayArea != null - ? displayArea.getConfiguration().windowConfiguration.getAppBounds() : null; + // the out bounds doesn't need to be restricted by the parent or current display. + final boolean customContainerPolicy = compatInsets != null; + if (!customContainerPolicy && windowingMode != WINDOWING_MODE_FREEFORM) { + final Rect containingAppBounds; + if (insideParentBounds) { + containingAppBounds = parentConfig.windowConfiguration.getAppBounds(); } else { - parentAppBounds = parentConfig.windowConfiguration.getAppBounds(); + // Restrict appBounds to display non-decor rather than parent because the override + // bounds are beyond the parent. Otherwise, it won't match the overridden bounds. + final TaskDisplayArea displayArea = getDisplayArea(); + containingAppBounds = displayArea != null + ? displayArea.getWindowConfiguration().getAppBounds() : null; } - if (parentAppBounds != null && !parentAppBounds.isEmpty()) { - outAppBounds.intersect(parentAppBounds); + if (containingAppBounds != null && !containingAppBounds.isEmpty()) { + outAppBounds.intersect(containingAppBounds); } } if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED || inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) { - if (insideParentBounds && WindowConfiguration.isFloating(windowingMode)) { + if (!customContainerPolicy && WindowConfiguration.isFloating(windowingMode)) { mTmpNonDecorBounds.set(mTmpFullBounds); mTmpStableBounds.set(mTmpFullBounds); - } else if (insideParentBounds + } else if (!customContainerPolicy && (overrideDisplayInfo != null || getDisplayContent() != null)) { final DisplayInfo di = overrideDisplayInfo != null ? overrideDisplayInfo @@ -2340,7 +2346,7 @@ class Task extends WindowContainer<WindowContainer> { if (rotation == ROTATION_UNDEFINED) { rotation = parentConfig.windowConfiguration.getRotation(); } - if (rotation != ROTATION_UNDEFINED && compatInsets != null) { + if (rotation != ROTATION_UNDEFINED && customContainerPolicy) { mTmpNonDecorBounds.set(mTmpFullBounds); mTmpStableBounds.set(mTmpFullBounds); compatInsets.getBoundsByRotation(mTmpBounds, rotation); @@ -2358,13 +2364,13 @@ class Task extends WindowContainer<WindowContainer> { if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) { final int overrideScreenWidthDp = (int) (mTmpStableBounds.width() / density); - inOutConfig.screenWidthDp = (insideParentBounds && !hasOverrideBounds) + inOutConfig.screenWidthDp = (insideParentBounds && !customContainerPolicy) ? Math.min(overrideScreenWidthDp, parentConfig.screenWidthDp) : overrideScreenWidthDp; } if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) { final int overrideScreenHeightDp = (int) (mTmpStableBounds.height() / density); - inOutConfig.screenHeightDp = (insideParentBounds && !hasOverrideBounds) + inOutConfig.screenHeightDp = (insideParentBounds && !customContainerPolicy) ? Math.min(overrideScreenHeightDp, parentConfig.screenHeightDp) : overrideScreenHeightDp; } @@ -2897,22 +2903,12 @@ class Task extends WindowContainer<WindowContainer> { if (!isRootTask) { adjustBoundsForDisplayChangeIfNeeded(dc); } - final DisplayContent prevDc = mDisplayContent; super.onDisplayChanged(dc); if (!isRootTask) { final int displayId = (dc != null) ? dc.getDisplayId() : INVALID_DISPLAY; mWmService.mAtmService.getTaskChangeNotificationController().notifyTaskDisplayChanged( mTaskId, displayId); } - if (prevDc != null && prevDc.mChangingContainers.remove(this)) { - // This gets called *after* this has been reparented to the new display. - // That reparenting resulted in this window changing modes (eg. FREEFORM -> FULLSCREEN), - // so this token is now "frozen" while waiting for the animation to start on prevDc - // (which will be cancelled since the window is no-longer a child). However, since this - // is no longer a child of prevDc, this won't be notified of the cancelled animation, - // so we need to cancel the change transition here. - mSurfaceFreezer.unfreeze(getPendingTransaction()); - } } boolean isResizeable(boolean checkSupportsPip) { @@ -4435,19 +4431,20 @@ class Task extends WindowContainer<WindowContainer> { // Let the old organizer know it has lost control. sendTaskVanished(); mTaskOrganizer = organizer; - sendTaskAppeared(); - onTaskOrganizerChanged(); - return true; - } - void taskOrganizerUnregistered() { - mTaskOrganizer = null; - mTaskAppearedSent = false; - mLastTaskOrganizerWindowingMode = -1; - onTaskOrganizerChanged(); - if (mCreatedByOrganizer) { - removeImmediately(); + if (mTaskOrganizer != null) { + sendTaskAppeared(); + } else { + // No longer managed by any organizer. + mTaskAppearedSent = false; + mLastTaskOrganizerWindowingMode = -1; + setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, false /* set */); + if (mCreatedByOrganizer) { + removeImmediately(); + } } + + return true; } /** @@ -4484,14 +4481,6 @@ class Task extends WindowContainer<WindowContainer> { return result; } - private void onTaskOrganizerChanged() { - if (mTaskOrganizer == null) { - // If this task is no longer controlled by a task organizer, then reset the force hidden - // state - setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, false /* set */); - } - } - @Override void setSurfaceControl(SurfaceControl sc) { super.setSurfaceControl(sc); diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 25791c762e42..3dc672396c29 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -123,6 +123,10 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { private final RootWindowContainer.FindTaskResult mTmpFindTaskResult = new RootWindowContainer.FindTaskResult(); + // Indicates whether the Assistant should show on top of the Dream (respectively, above + // everything else on screen). Otherwise, it will be put under always-on-top stacks. + private final boolean mAssistantOnTopOfDream; + /** * If this is the same as {@link #getFocusedStack} then the activity on the top of the focused * stack has been resumed. If stacks are changing position this will hold the old stack until @@ -148,6 +152,9 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { mDisplayContent = displayContent; mRootWindowContainer = service.mRoot; mAtmService = service.mAtmService; + + mAssistantOnTopOfDream = mWmService.mContext.getResources().getBoolean( + com.android.internal.R.bool.config_assistantOnTopOfDream); } /** @@ -327,55 +334,80 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { } /** - * When stack is added or repositioned, find a proper position for it. - * This will make sure that pinned stack always stays on top. - * @param requestedPosition Position requested by caller. - * @param stack Stack to be added or positioned. - * @param adding Flag indicates whether we're adding a new stack or positioning an existing. - * @return The proper position for the stack. + * Assigns a priority number to stack types. This priority defines an order between the types + * of stacks that are added to the task display area. + * + * Higher priority number indicates that the stack should have a higher z-order. + * + * @return the priority of the stack */ - private int findPositionForStack(int requestedPosition, ActivityStack stack, - boolean adding) { - if (stack.isActivityTypeDream()) { - return POSITION_TOP; - } - - if (stack.inPinnedWindowingMode()) { - return POSITION_TOP; - } - - final int topChildPosition = mChildren.size() - 1; - int belowAlwaysOnTopPosition = POSITION_BOTTOM; - for (int i = topChildPosition; i >= 0; --i) { - // Since a stack could be repositioned while being one of the child, return - // current index if that's the same stack we are positioning and it is always on - // top. - final boolean sameStack = mChildren.get(i) == stack; - if ((sameStack && stack.isAlwaysOnTop()) - || (!sameStack && !mChildren.get(i).isAlwaysOnTop())) { - belowAlwaysOnTopPosition = i; + private int getPriority(ActivityStack stack) { + if (mAssistantOnTopOfDream && stack.isActivityTypeAssistant()) return 4; + if (stack.isActivityTypeDream()) return 3; + if (stack.inPinnedWindowingMode()) return 2; + if (stack.isAlwaysOnTop()) return 1; + return 0; + } + + private int findMinPositionForStack(ActivityStack stack) { + int minPosition = POSITION_BOTTOM; + for (int i = 0; i < mChildren.size(); ++i) { + if (getPriority(getStackAt(i)) < getPriority(stack)) { + minPosition = i; + } else { break; } } - // The max possible position we can insert the stack at. - int maxPosition = POSITION_TOP; - // The min possible position we can insert the stack at. - int minPosition = POSITION_BOTTOM; - if (stack.isAlwaysOnTop()) { - if (hasPinnedTask()) { - // Always-on-top stacks go below the pinned stack. - maxPosition = mChildren.indexOf(mRootPinnedTask) - 1; + // Since a stack could be repositioned while still being one of the children, we check + // if this always-on-top stack already exists and if so, set the minPosition to its + // previous position. + final int currentIndex = getIndexOf(stack); + if (currentIndex > minPosition) { + minPosition = currentIndex; } - // Always-on-top stacks need to be above all other stacks. - minPosition = belowAlwaysOnTopPosition - != POSITION_BOTTOM ? belowAlwaysOnTopPosition : topChildPosition; - } else { - // Other stacks need to be below the always-on-top stacks. - maxPosition = belowAlwaysOnTopPosition - != POSITION_BOTTOM ? belowAlwaysOnTopPosition : 0; } + return minPosition; + } + + private int findMaxPositionForStack(ActivityStack stack) { + for (int i = mChildren.size() - 1; i >= 0; --i) { + final ActivityStack curr = getStackAt(i); + // Since a stack could be repositioned while still being one of the children, we check + // if 'curr' is the same stack and skip it if so + final boolean sameStack = curr == stack; + if (getPriority(curr) <= getPriority(stack) && !sameStack) { + return i; + } + } + return 0; + } + + /** + * When stack is added or repositioned, find a proper position for it. + * + * The order is defined as: + * - Dream is on top of everything + * - PiP is directly below the Dream + * - always-on-top stacks are directly below PiP; new always-on-top stacks are added above + * existing ones + * - other non-always-on-top stacks come directly below always-on-top stacks; new + * non-always-on-top stacks are added directly below always-on-top stacks and above existing + * non-always-on-top stacks + * - if {@link #mAssistantOnTopOfDream} is enabled, then Assistant is on top of everything + * (including the Dream); otherwise, it is a normal non-always-on-top stack + * + * @param requestedPosition Position requested by caller. + * @param stack Stack to be added or positioned. + * @param adding Flag indicates whether we're adding a new stack or positioning an existing. + * @return The proper position for the stack. + */ + private int findPositionForStack(int requestedPosition, ActivityStack stack, boolean adding) { + // The max possible position we can insert the stack at. + int maxPosition = findMaxPositionForStack(stack); + // The min possible position we can insert the stack at. + int minPosition = findMinPositionForStack(stack); // Cap the requested position to something reasonable for the previous position check // below. diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index adc50bf70446..306c100e651c 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -218,18 +218,24 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } void dispose() { - releaseTasks(); + // Move organizer from managing specific windowing modes for (int i = mTaskOrganizersForWindowingMode.size() - 1; i >= 0; --i) { mTaskOrganizersForWindowingMode.valueAt(i).remove(mOrganizer.getBinder()); } - } - private void releaseTasks() { - for (int i = mOrganizedTasks.size() - 1; i >= 0; i--) { - final Task t = mOrganizedTasks.get(i); - removeTask(t); - t.taskOrganizerUnregistered(); + // Update tasks currently managed by this organizer to the next one available if + // possible. + while (!mOrganizedTasks.isEmpty()) { + final Task t = mOrganizedTasks.get(0); + t.updateTaskOrganizerState(true /* forceUpdate */); + if (mOrganizedTasks.contains(t)) { + removeTask(t); + } } + + // Remove organizer state after removing tasks so we get a chance to send + // onTaskVanished. + mTaskOrganizerStates.remove(asBinder()); } void unlinkDeath() { @@ -313,16 +319,11 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { new TaskOrganizerState(organizer, uid)); } - if (orgs.size() == 1) { - // Only in the case where this is the root task organizer for the given - // windowing mode, we add report all existing tasks in that mode to the new - // task organizer. - mService.mRootWindowContainer.forAllTasks((task) -> { - if (task.getWindowingMode() == windowingMode) { - task.updateTaskOrganizerState(true /* forceUpdate */); - } - }); - } + mService.mRootWindowContainer.forAllTasks((task) -> { + if (task.getWindowingMode() == windowingMode) { + task.updateTaskOrganizerState(true /* forceUpdate */); + } + }); } } finally { Binder.restoreCallingIdentity(origId); @@ -335,7 +336,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { - final TaskOrganizerState state = mTaskOrganizerStates.remove(organizer.asBinder()); + final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder()); if (state == null) { return; } @@ -367,7 +368,9 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { void onTaskVanished(ITaskOrganizer organizer, Task task) { final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder()); - state.removeTask(task); + if (state != null) { + state.removeTask(task); + } } @Override diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java index 203ca25ecf6e..5f3c63352015 100644 --- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java +++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS; @@ -45,6 +46,7 @@ class WallpaperWindowToken extends WindowToken { DisplayContent dc, boolean ownerCanManageAppTokens) { super(service, token, TYPE_WALLPAPER, explicit, dc, ownerCanManageAppTokens); dc.mWallpaperController.addWallpaperToken(this); + setWindowingMode(WINDOWING_MODE_FULLSCREEN); } @Override diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index f3e2992d5913..591bc5475cd7 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -526,6 +526,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< */ @CallSuper void removeImmediately() { + final DisplayContent dc = getDisplayContent(); + if (dc != null) { + mSurfaceFreezer.unfreeze(getPendingTransaction()); + dc.mChangingContainers.remove(this); + } while (!mChildren.isEmpty()) { final E child = mChildren.peekLast(); child.removeImmediately(); @@ -718,6 +723,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< * @param dc The display this container is on after changes. */ void onDisplayChanged(DisplayContent dc) { + if (mDisplayContent != null && mDisplayContent.mChangingContainers.remove(this)) { + // Cancel any change transition queued-up for this container on the old display. + mSurfaceFreezer.unfreeze(getPendingTransaction()); + } mDisplayContent = dc; if (dc != null && dc != this) { dc.getPendingTransaction().merge(mPendingTransaction); @@ -2033,6 +2042,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< void cancelAnimation() { mSurfaceAnimator.cancelAnimation(); + mSurfaceFreezer.unfreeze(getPendingTransaction()); } @Override diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 51095ee85eea..8eb4b2659cc0 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -23,6 +23,7 @@ import static android.Manifest.permission.MANAGE_APP_TOKENS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS; import static android.Manifest.permission.RESTRICTED_VR_ACCESS; +import static android.Manifest.permission.STATUS_BAR_SERVICE; import static android.Manifest.permission.WRITE_SECURE_SETTINGS; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; @@ -74,6 +75,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED; import static android.view.WindowManagerGlobal.ADD_OKAY; +import static android.view.WindowManagerGlobal.ADD_TOO_MANY_TOKENS; import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY; import static android.view.WindowManagerGlobal.RELAYOUT_RES_BLAST_SYNC; import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; @@ -413,6 +415,12 @@ public class WindowManagerService extends IWindowManager.Stub private static final int ANIMATION_COMPLETED_TIMEOUT_MS = 5000; + /** The maximum count of window tokens without surface that an app can register. */ + private static final int MAXIMUM_WINDOW_TOKEN_COUNT_WITHOUT_SURFACE = 5; + + /** System UI can create more window context... */ + private static final int SYSTEM_UI_MULTIPLIER = 2; + // TODO(b/143053092): Remove the settings if it becomes stable. private static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform"; boolean mIsFixedRotationTransformEnabled; @@ -2594,10 +2602,30 @@ public class WindowManagerService extends IWindowManager.Stub @Override public int addWindowTokenWithOptions(IBinder binder, int type, int displayId, Bundle options, String packageName) { + if (tokenCountExceed()) { + return ADD_TOO_MANY_TOKENS; + } return addWindowTokenWithOptions(binder, type, displayId, options, packageName, true /* fromClientToken */); } + private boolean tokenCountExceed() { + final int callingUid = Binder.getCallingUid(); + // Don't check if caller is from system server. + if (callingUid == myPid()) { + return false; + } + final int limit = + (checkCallingPermission(STATUS_BAR_SERVICE, "addWindowTokenWithOptions")) + ? MAXIMUM_WINDOW_TOKEN_COUNT_WITHOUT_SURFACE * SYSTEM_UI_MULTIPLIER + : MAXIMUM_WINDOW_TOKEN_COUNT_WITHOUT_SURFACE; + synchronized (mGlobalLock) { + int[] count = new int[1]; + mRoot.forAllDisplays(d -> count[0] += d.getWindowTokensWithoutSurfaceCount(callingUid)); + return count[0] >= limit; + } + } + private int addWindowTokenWithOptions(IBinder binder, int type, int displayId, Bundle options, String packageName, boolean fromClientToken) { final boolean callerCanManageAppTokens = @@ -6111,15 +6139,6 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mInputMethodInputTarget in display# "); pw.print(displayId); pw.print(' '); pw.println(inputMethodInputTarget); } - if (mAccessibilityController != null) { - final Region magnificationRegion = new Region(); - mAccessibilityController.getMagnificationRegionLocked(displayId, - magnificationRegion); - pw.print(" mMagnificationRegion in display# "); - pw.print(displayId); - pw.print(' '); - pw.println(magnificationRegion); - } }); pw.print(" mInTouchMode="); pw.println(mInTouchMode); pw.print(" mLastDisplayFreezeDuration="); @@ -6135,6 +6154,9 @@ public class WindowManagerService extends IWindowManager.Stub mInputManagerCallback.dump(pw, " "); mTaskSnapshotController.dump(pw, " "); + if (mAccessibilityController != null) { + mAccessibilityController.dump(pw, " "); + } if (dumpAll) { final WindowState imeWindow = mRoot.getCurrentInputMethodWindow(); @@ -7656,15 +7678,8 @@ public class WindowManagerService extends IWindowManager.Stub Slog.w(TAG, "Cannot find window which accessibility connection is added to"); return; } - try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) { - t.setMetadata( - state.mSurfaceControl, - SurfaceControl.METADATA_ACCESSIBILITY_ID, - accessibilityWindowId); - t.apply(); - } finally { - SurfaceControl.closeTransaction(); - } + mTransaction.setMetadata(state.mSurfaceControl, + SurfaceControl.METADATA_ACCESSIBILITY_ID, accessibilityWindowId).apply(); } } diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 194ed3ec3b0e..41bd70726e71 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -40,6 +40,7 @@ import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_K import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; +import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; @@ -50,6 +51,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.ServiceInfo; import android.content.res.Configuration; import android.os.Build; import android.os.Message; @@ -165,7 +167,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // Thread currently set for VR scheduling int mVrThreadTid; - boolean mIsImeProcess; + // Whether this process has ever started a service with the BIND_INPUT_METHOD permission. + private volatile boolean mHasImeService; // all activities running in the process private final ArrayList<ActivityRecord> mActivities = new ArrayList<>(); @@ -187,6 +190,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // Registered display id as a listener to override config change private int mDisplayId; private ActivityRecord mConfigActivityRecord; + // Whether the activity config override is allowed for this process. + private volatile boolean mIsActivityConfigOverrideAllowed = true; /** * Activities that hosts some UI drawn by the current process. The activities live * in another process. This is used to check if the process is currently showing anything @@ -201,9 +206,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio /** Whether our process is currently running a {@link IRemoteAnimationRunner} */ private boolean mRunningRemoteAnimation; - /** Whether this process is owned by the System UI package. */ - final boolean mIsSysUiPackage; - public WindowProcessController(@NonNull ActivityTaskManagerService atm, ApplicationInfo info, String name, int uid, int userId, Object owner, WindowProcessListener listener) { mInfo = info; @@ -215,8 +217,13 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio mAtm = atm; mDisplayId = INVALID_DISPLAY; - mIsSysUiPackage = info.packageName.equals( + boolean isSysUiPackage = info.packageName.equals( mAtm.getSysUiServiceComponentLocked().getPackageName()); + if (isSysUiPackage || mUid == Process.SYSTEM_UID) { + // This is a system owned process and should not use an activity config. + // TODO(b/151161907): Remove after support for display-independent (raw) SysUi configs. + mIsActivityConfigOverrideAllowed = false; + } onConfigurationChanged(atm.getGlobalConfiguration()); } @@ -1095,9 +1102,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio * always track the configuration of the non-finishing activity last added to the process. */ private void updateActivityConfigurationListener() { - if (mIsSysUiPackage || mUid == Process.SYSTEM_UID) { - // This is a system owned process and should not use an activity config. - // TODO(b/151161907): Remove after support for display-independent (raw) SysUi configs. + if (!mIsActivityConfigOverrideAllowed) { return; } @@ -1132,7 +1137,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio final Configuration config = getConfiguration(); if (mLastReportedConfiguration.diff(config) == 0) { // Nothing changed. - if (Build.IS_DEBUGGABLE && mIsImeProcess) { + if (Build.IS_DEBUGGABLE && mHasImeService) { // TODO (b/135719017): Temporary log for debugging IME service. Slog.w(TAG_CONFIGURATION, "Current config: " + config + " unchanged for IME proc " + mName); @@ -1156,7 +1161,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio private void dispatchConfigurationChange(Configuration config) { if (mThread == null) { - if (Build.IS_DEBUGGABLE && mIsImeProcess) { + if (Build.IS_DEBUGGABLE && mHasImeService) { // TODO (b/135719017): Temporary log for debugging IME service. Slog.w(TAG_CONFIGURATION, "Unable to send config for IME proc " + mName + ": no app thread"); @@ -1166,7 +1171,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio if (DEBUG_CONFIGURATION) { Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName + " new config " + config); } - if (Build.IS_DEBUGGABLE && mIsImeProcess) { + if (Build.IS_DEBUGGABLE && mHasImeService) { // TODO (b/135719017): Temporary log for debugging IME service. Slog.v(TAG_CONFIGURATION, "Sending to IME proc " + mName + " new config " + config); } @@ -1286,6 +1291,35 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio } } + /** + * Called to notify {@link WindowProcessController} of a started service. + * + * @param serviceInfo information describing the started service. + */ + public void onServiceStarted(ServiceInfo serviceInfo) { + String permission = serviceInfo.permission; + if (permission == null) { + return; + } + + // TODO: Audit remaining services for disabling activity override (Wallpaper, Dream, etc). + switch (permission) { + case Manifest.permission.BIND_INPUT_METHOD: + mHasImeService = true; + // Fall-through + case Manifest.permission.BIND_ACCESSIBILITY_SERVICE: + case Manifest.permission.BIND_VOICE_INTERACTION: + // We want to avoid overriding the config of these services with that of the + // activity as it could lead to incorrect display metrics. For ex, IME services + // expect their config to match the config of the display with the IME window + // showing. + mIsActivityConfigOverrideAllowed = false; + break; + default: + break; + } + } + @HotPath(caller = HotPath.OOM_ADJUSTMENT) public void onTopProcChanged() { synchronized (mAtm.mGlobalLockWithoutBoost) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index ef690e1db396..bbe5d942874d 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3660,9 +3660,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mActivityRecord.getBounds().equals(mTmpRect); } - @Override - public boolean isLetterboxedOverlappingWith(Rect rect) { - return mActivityRecord != null && mActivityRecord.isLetterboxOverlappingWith(rect); + /** + * @see Letterbox#notIntersectsOrFullyContains(Rect) + */ + boolean letterboxNotIntersectsOrFullyContains(Rect rect) { + return mActivityRecord == null + || mActivityRecord.letterboxNotIntersectsOrFullyContains(rect); } boolean isDragResizeChanged() { diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 99577077d65d..bfe3b2890bc1 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -884,8 +884,8 @@ class WindowStateAnimator { clipRect = mTmpClipRect; } - if (mSurfaceResized && (mAttrType == TYPE_BASE_APPLICATION) && - (task != null) && (task.getMainWindowSizeChangeTransaction() != null)) { + if (w.mInRelayout && (mAttrType == TYPE_BASE_APPLICATION) && (task != null) + && (task.getMainWindowSizeChangeTransaction() != null)) { mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(), mWin.getFrameNumber()); SurfaceControl.mergeToGlobalTransaction(task.getMainWindowSizeChangeTransaction()); @@ -1476,6 +1476,7 @@ class WindowStateAnimator { if (dumpAll) { pw.print(prefix); pw.print("mDrawState="); pw.print(drawStateToString()); pw.print(prefix); pw.print(" mLastHidden="); pw.println(mLastHidden); + pw.print(prefix); pw.print("mEnterAnimationPending=" + mEnterAnimationPending); pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw); pw.print(" mLastClipRect="); mLastClipRect.printShortString(pw); diff --git a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp index e32a343433a8..6cf81335e52d 100644 --- a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp +++ b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp @@ -69,14 +69,9 @@ static constexpr auto PollTimeoutMs = 5000; struct JniIds { jclass packageManagerShellCommandDataLoader; jmethodID pmscdLookupShellCommand; - jmethodID pmscdGetStdInPFD; + jmethodID pmscdGetStdIn; jmethodID pmscdGetLocalFile; - jmethodID parcelFileDescriptorGetFileDescriptor; - - jclass ioUtils; - jmethodID ioUtilsCloseQuietly; - JniIds(JNIEnv* env) { packageManagerShellCommandDataLoader = (jclass)env->NewGlobalRef( FindClassOrDie(env, "com/android/server/pm/PackageManagerShellCommandDataLoader")); @@ -84,23 +79,11 @@ struct JniIds { GetStaticMethodIDOrDie(env, packageManagerShellCommandDataLoader, "lookupShellCommand", "(Ljava/lang/String;)Landroid/os/ShellCommand;"); - pmscdGetStdInPFD = - GetStaticMethodIDOrDie(env, packageManagerShellCommandDataLoader, "getStdInPFD", - "(Landroid/os/ShellCommand;)Landroid/os/" - "ParcelFileDescriptor;"); + pmscdGetStdIn = GetStaticMethodIDOrDie(env, packageManagerShellCommandDataLoader, + "getStdIn", "(Landroid/os/ShellCommand;)I"); pmscdGetLocalFile = GetStaticMethodIDOrDie(env, packageManagerShellCommandDataLoader, "getLocalFile", - "(Landroid/os/ShellCommand;Ljava/lang/String;)Landroid/os/" - "ParcelFileDescriptor;"); - - auto parcelFileDescriptor = FindClassOrDie(env, "android/os/ParcelFileDescriptor"); - parcelFileDescriptorGetFileDescriptor = - GetMethodIDOrDie(env, parcelFileDescriptor, "getFileDescriptor", - "()Ljava/io/FileDescriptor;"); - - ioUtils = (jclass)env->NewGlobalRef(FindClassOrDie(env, "libcore/io/IoUtils")); - ioUtilsCloseQuietly = GetStaticMethodIDOrDie(env, ioUtils, "closeQuietly", - "(Ljava/lang/AutoCloseable;)V"); + "(Landroid/os/ShellCommand;Ljava/lang/String;)I"); } }; @@ -211,22 +194,6 @@ static inline IncFsSize verityTreeSizeForFile(IncFsSize fileSize) { return total_tree_block_count * INCFS_DATA_FILE_BLOCK_SIZE; } -static inline unique_fd convertPfdToFdAndDup(JNIEnv* env, const JniIds& jni, jobject pfd) { - if (!pfd) { - ALOGE("Missing In ParcelFileDescriptor."); - return {}; - } - auto managedFd = env->CallObjectMethod(pfd, jni.parcelFileDescriptorGetFileDescriptor); - if (!pfd) { - ALOGE("Missing In FileDescriptor."); - return {}; - } - unique_fd result{dup(jniGetFDFromFileDescriptor(env, managedFd))}; - // Can be closed after dup. - env->CallStaticVoidMethod(jni.ioUtils, jni.ioUtilsCloseQuietly, pfd); - return result; -} - enum MetadataMode : int8_t { STDIN = 0, LOCAL_FILE = 1, @@ -263,11 +230,9 @@ static inline InputDescs openLocalFile(JNIEnv* env, const JniIds& jni, jobject s const std::string idsigPath = filePath + ".idsig"; - auto idsigFd = convertPfdToFdAndDup( - env, jni, - env->CallStaticObjectMethod(jni.packageManagerShellCommandDataLoader, - jni.pmscdGetLocalFile, shellCommand, - env->NewStringUTF(idsigPath.c_str()))); + unique_fd idsigFd{env->CallStaticIntMethod(jni.packageManagerShellCommandDataLoader, + jni.pmscdGetLocalFile, shellCommand, + env->NewStringUTF(idsigPath.c_str()))}; if (idsigFd.ok()) { auto treeSize = verityTreeSizeForFile(size); auto actualTreeSize = skipIdSigHeaders(idsigFd); @@ -283,11 +248,9 @@ static inline InputDescs openLocalFile(JNIEnv* env, const JniIds& jni, jobject s }); } - auto fileFd = convertPfdToFdAndDup( - env, jni, - env->CallStaticObjectMethod(jni.packageManagerShellCommandDataLoader, - jni.pmscdGetLocalFile, shellCommand, - env->NewStringUTF(filePath.c_str()))); + unique_fd fileFd{env->CallStaticIntMethod(jni.packageManagerShellCommandDataLoader, + jni.pmscdGetLocalFile, shellCommand, + env->NewStringUTF(filePath.c_str()))}; if (fileFd.ok()) { result.push_back(InputDesc{ .fd = std::move(fileFd), @@ -307,10 +270,8 @@ static inline InputDescs openInputs(JNIEnv* env, const JniIds& jni, jobject shel std::string(metadata.data, metadata.size)); } - auto fd = convertPfdToFdAndDup( - env, jni, - env->CallStaticObjectMethod(jni.packageManagerShellCommandDataLoader, - jni.pmscdGetStdInPFD, shellCommand)); + unique_fd fd{env->CallStaticIntMethod(jni.packageManagerShellCommandDataLoader, + jni.pmscdGetStdIn, shellCommand)}; if (!fd.ok()) { return {}; } diff --git a/services/core/jni/com_android_server_tv_TvUinputBridge.cpp b/services/core/jni/com_android_server_tv_TvUinputBridge.cpp index 6e2e2c54518b..99deab4fd652 100644 --- a/services/core/jni/com_android_server_tv_TvUinputBridge.cpp +++ b/services/core/jni/com_android_server_tv_TvUinputBridge.cpp @@ -106,7 +106,7 @@ static int getGamepadkeyCode(int32_t androidKeyCode) { static const GamepadAxis* getGamepadAxis(int32_t androidAxisCode) { std::unordered_map<int32_t, int>::iterator it = gamepadAndroidAxisToIndexMap.find(androidAxisCode); - if (it == gamepadAndroidToLinuxKeyMap.end()) { + if (it == gamepadAndroidAxisToIndexMap.end()) { return nullptr; } return &GAMEPAD_AXES[it->second]; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 7b845557cf73..5d5e424db017 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -403,11 +403,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * MS_PER_DAY; // 5 days, in ms private static final long MANAGED_PROFILE_MAXIMUM_TIME_OFF_THRESHOLD = 3 * MS_PER_DAY; + /** When to warn the user about the approaching work profile off deadline: 1 day before */ + private static final long MANAGED_PROFILE_OFF_WARNING_PERIOD = 1 * MS_PER_DAY; private static final String ACTION_EXPIRED_PASSWORD_NOTIFICATION = "com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION"; - private static final String ACTION_PROFILE_OFF_DEADLINE = + @VisibleForTesting + static final String ACTION_PROFILE_OFF_DEADLINE = "com.android.server.ACTION_PROFILE_OFF_DEADLINE"; private static final String ATTR_PERMISSION_PROVIDER = "permission-provider"; @@ -649,6 +652,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private static final boolean ENABLE_LOCK_GUARD = true; + /** Profile off deadline is not set or more than MANAGED_PROFILE_OFF_WARNING_PERIOD away. */ + private static final int PROFILE_OFF_DEADLINE_DEFAULT = 0; + /** Profile off deadline is closer than MANAGED_PROFILE_OFF_WARNING_PERIOD. */ + private static final int PROFILE_OFF_DEADLINE_WARNING = 1; + /** Profile off deadline reached, notify the user that personal apps blocked. */ + private static final int PROFILE_OFF_DEADLINE_REACHED = 2; + interface Stats { int LOCK_GUARD_GUARD = 0; @@ -926,11 +936,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mUserData.remove(userHandle); } handlePackagesChanged(null /* check all admins */, userHandle); + updatePersonalAppsSuspensionOnUserStart(userHandle); } else if (Intent.ACTION_USER_STOPPED.equals(action)) { sendDeviceOwnerUserCommand(DeviceAdminReceiver.ACTION_USER_STOPPED, userHandle); if (isManagedProfile(userHandle)) { Slog.d(LOG_TAG, "Managed profile was stopped"); - updatePersonalAppSuspension(userHandle, false /* profileIsOn */); + updatePersonalAppsSuspension(userHandle, false /* unlocked */); } } else if (Intent.ACTION_USER_SWITCHED.equals(action)) { sendDeviceOwnerUserCommand(DeviceAdminReceiver.ACTION_USER_SWITCHED, userHandle); @@ -940,7 +951,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } if (isManagedProfile(userHandle)) { Slog.d(LOG_TAG, "Managed profile became unlocked"); - updatePersonalAppSuspension(userHandle, true /* profileIsOn */); + updatePersonalAppsSuspension(userHandle, true /* unlocked */); } } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { handlePackagesChanged(null /* check all admins */, userHandle); @@ -967,7 +978,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Slog.i(LOG_TAG, "Profile off deadline alarm was triggered"); final int userId = getManagedUserId(UserHandle.USER_SYSTEM); if (userId >= 0) { - updatePersonalAppSuspension(userId, mUserManager.isUserUnlocked(userId)); + updatePersonalAppsSuspension(userId, mUserManager.isUserUnlocked(userId)); } else { Slog.wtf(LOG_TAG, "Got deadline alarm for nonexistent profile"); } @@ -2486,6 +2497,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { public void runCryptoSelfTest() { CryptoTestHelper.runAndLogSelfTest(); } + + public String[] getPersonalAppsForSuspension(int userId) { + return new PersonalAppsSuspensionHelper( + mContext.createContextAsUser(UserHandle.of(userId), 0 /* flags */)) + .getPersonalAppsForSuspension(); + } + + public long systemCurrentTimeMillis() { + return System.currentTimeMillis(); + } } /** @@ -4045,10 +4066,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { applyManagedProfileRestrictionIfDeviceOwnerLocked(); } maybeStartSecurityLogMonitorOnActivityManagerReady(); - final int userId = getManagedUserId(UserHandle.USER_SYSTEM); - if (userId >= 0) { - updatePersonalAppSuspension(userId, false /* running */); - } break; case SystemService.PHASE_BOOT_COMPLETED: ensureDeviceOwnerUserStarted(); // TODO Consider better place to do this. @@ -4056,6 +4073,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } + private void updatePersonalAppsSuspensionOnUserStart(int userHandle) { + final int profileUserHandle = getManagedUserId(userHandle); + if (profileUserHandle >= 0) { + // Given that the parent user has just started, profile should be locked. + updatePersonalAppsSuspension(profileUserHandle, false /* unlocked */); + } else { + suspendPersonalAppsInternal(userHandle, false); + } + } + private void onLockSettingsReady() { getUserData(UserHandle.USER_SYSTEM); loadOwners(); @@ -15893,11 +15920,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - final int suspendedState = suspended - ? PERSONAL_APPS_SUSPENDED_EXPLICITLY - : PERSONAL_APPS_NOT_SUSPENDED; - mInjector.binderWithCleanCallingIdentity( - () -> applyPersonalAppsSuspension(callingUserId, suspendedState)); + mInjector.binderWithCleanCallingIdentity(() -> updatePersonalAppsSuspension( + callingUserId, mUserManager.isUserUnlocked(callingUserId))); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_PERSONAL_APPS_SUSPENDED) @@ -15907,44 +15931,54 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } /** - * Checks whether there is a policy that requires personal apps to be suspended and if so, - * applies it. - * @param running whether the profile is currently considered running. + * Checks whether personal apps should be suspended according to the policy and applies the + * change if needed. + * + * @param unlocked whether the profile is currently running unlocked. */ - private void updatePersonalAppSuspension(int profileUserId, boolean running) { - final int suspensionState; + private void updatePersonalAppsSuspension(int profileUserId, boolean unlocked) { + final boolean suspended; synchronized (getLockObject()) { final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(profileUserId); if (profileOwner != null) { - final boolean deadlineReached = - updateProfileOffDeadlineLocked(profileUserId, profileOwner, running); - suspensionState = makeSuspensionReasons( - profileOwner.mSuspendPersonalApps, deadlineReached); - Slog.d(LOG_TAG, - String.format("New personal apps suspension state: %d", suspensionState)); + final int deadlineState = + updateProfileOffDeadlineLocked(profileUserId, profileOwner, unlocked); + suspended = profileOwner.mSuspendPersonalApps + || deadlineState == PROFILE_OFF_DEADLINE_REACHED; + Slog.d(LOG_TAG, String.format("Personal apps suspended: %b, deadline state: %d", + suspended, deadlineState)); + updateProfileOffDeadlineNotificationLocked(profileUserId, profileOwner, + unlocked ? PROFILE_OFF_DEADLINE_DEFAULT : deadlineState); } else { - suspensionState = PERSONAL_APPS_NOT_SUSPENDED; + suspended = false; } } - applyPersonalAppsSuspension(profileUserId, suspensionState); + final int parentUserId = getProfileParentId(profileUserId); + suspendPersonalAppsInternal(parentUserId, suspended); } /** * Checks work profile time off policy, scheduling personal apps suspension via alarm if * necessary. - * @return whether the apps should be suspended based on maximum time off policy. + * @return profile deadline state */ - private boolean updateProfileOffDeadlineLocked( + private int updateProfileOffDeadlineLocked( int profileUserId, ActiveAdmin profileOwner, boolean unlocked) { - final long now = System.currentTimeMillis(); + final long now = mInjector.systemCurrentTimeMillis(); if (profileOwner.mProfileOffDeadline != 0 && now > profileOwner.mProfileOffDeadline) { // Profile off deadline is already reached. Slog.i(LOG_TAG, "Profile off deadline has been reached."); - return true; + return PROFILE_OFF_DEADLINE_REACHED; } boolean shouldSaveSettings = false; - if (profileOwner.mProfileOffDeadline != 0 + if (profileOwner.mSuspendPersonalApps) { + // When explicit suspension is active, deadline shouldn't be set. + if (profileOwner.mProfileOffDeadline != 0) { + profileOwner.mProfileOffDeadline = 0; + shouldSaveSettings = true; + } + } else if (profileOwner.mProfileOffDeadline != 0 && (profileOwner.mProfileMaximumTimeOffMillis == 0 || unlocked)) { // There is a deadline but either there is no policy or the profile is unlocked -> clear // the deadline. @@ -15960,52 +15994,51 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { shouldSaveSettings = true; } - updateProfileOffAlarm(profileOwner.mProfileOffDeadline); - if (shouldSaveSettings) { saveSettingsLocked(profileUserId); } - return false; - } - private void updateProfileOffAlarm(long profileOffDeadline) { + final long alarmTime; + final int deadlineState; + if (profileOwner.mProfileOffDeadline == 0) { + alarmTime = 0; + deadlineState = PROFILE_OFF_DEADLINE_DEFAULT; + } else if (profileOwner.mProfileOffDeadline - now < MANAGED_PROFILE_OFF_WARNING_PERIOD) { + // The deadline is close, upon the alarm personal apps should be suspended. + alarmTime = profileOwner.mProfileOffDeadline; + deadlineState = PROFILE_OFF_DEADLINE_WARNING; + } else { + // The deadline is quite far, upon the alarm we should warn the user first, so the + // alarm is scheduled earlier than the actual deadline. + alarmTime = profileOwner.mProfileOffDeadline - MANAGED_PROFILE_OFF_WARNING_PERIOD; + deadlineState = PROFILE_OFF_DEADLINE_DEFAULT; + } + final AlarmManager am = mInjector.getAlarmManager(); final PendingIntent pi = mInjector.pendingIntentGetBroadcast( mContext, REQUEST_PROFILE_OFF_DEADLINE, new Intent(ACTION_PROFILE_OFF_DEADLINE), PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT); - am.cancel(pi); - if (profileOffDeadline != 0) { - Slog.i(LOG_TAG, "Profile off deadline alarm is set."); - am.set(AlarmManager.RTC, profileOffDeadline, pi); - } else { - Slog.i(LOG_TAG, "Profile off deadline alarm is removed."); - } - } - - private void applyPersonalAppsSuspension( - int profileUserId, @PersonalAppsSuspensionReason int suspensionState) { - final boolean suspended = getUserData(UserHandle.USER_SYSTEM).mAppsSuspended; - final boolean shouldSuspend = suspensionState != PERSONAL_APPS_NOT_SUSPENDED; - if (suspended != shouldSuspend) { - suspendPersonalAppsInternal(shouldSuspend, UserHandle.USER_SYSTEM); - } - if (suspensionState == PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT) { - sendPersonalAppsSuspendedNotification(profileUserId); + if (alarmTime == 0) { + Slog.i(LOG_TAG, "Profile off deadline alarm is removed."); + am.cancel(pi); } else { - clearPersonalAppsSuspendedNotification(); + Slog.i(LOG_TAG, "Profile off deadline alarm is set."); + am.set(AlarmManager.RTC, alarmTime, pi); } + + return deadlineState; } - private void suspendPersonalAppsInternal(boolean suspended, int userId) { + private void suspendPersonalAppsInternal(int userId, boolean suspended) { + if (getUserData(userId).mAppsSuspended == suspended) { + return; + } Slog.i(LOG_TAG, String.format("%s personal apps for user %d", suspended ? "Suspending" : "Unsuspending", userId)); mInjector.binderWithCleanCallingIdentity(() -> { try { - final String[] appsToSuspend = - new PersonalAppsSuspensionHelper( - mContext.createContextAsUser(UserHandle.of(userId), 0 /* flags */)) - .getPersonalAppsForSuspension(); + final String[] appsToSuspend = mInjector.getPersonalAppsForSuspension(userId); final String[] failedPackages = mIPackageManager.setPackagesSuspendedAsUser( appsToSuspend, suspended, null, null, null, PLATFORM_PACKAGE_NAME, userId); if (!ArrayUtils.isEmpty(failedPackages)) { @@ -16024,37 +16057,38 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private void clearPersonalAppsSuspendedNotification() { - mInjector.binderWithCleanCallingIdentity(() -> - mInjector.getNotificationManager().cancel( - SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED)); - } + private void updateProfileOffDeadlineNotificationLocked(int profileUserId, + @Nullable ActiveAdmin profileOwner, int notificationState) { - private void sendPersonalAppsSuspendedNotification(int userId) { - final String profileOwnerPackageName; - final long maxTimeOffDays; - synchronized (getLockObject()) { - profileOwnerPackageName = mOwners.getProfileOwnerComponent(userId).getPackageName(); - final ActiveAdmin poAdmin = getProfileOwnerAdminLocked(userId); - maxTimeOffDays = TimeUnit.MILLISECONDS.toDays(poAdmin.mProfileMaximumTimeOffMillis); + if (notificationState == PROFILE_OFF_DEADLINE_DEFAULT) { + mInjector.getNotificationManager().cancel(SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED); + return; } + final String profileOwnerPackageName = profileOwner.info.getPackageName(); + final long maxTimeOffDays = + TimeUnit.MILLISECONDS.toDays(profileOwner.mProfileMaximumTimeOffMillis); + final Intent intent = new Intent(DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE); intent.setPackage(profileOwnerPackageName); final PendingIntent pendingIntent = mInjector.pendingIntentGetActivityAsUser(mContext, - 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT, null /* options */, - UserHandle.of(userId)); + 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT, + null /* options */, UserHandle.of(profileUserId)); + + // TODO(b/149075510): Only the first of the notifications should be dismissible. + final String title = mContext.getString( + notificationState == PROFILE_OFF_DEADLINE_WARNING + ? R.string.personal_apps_suspended_tomorrow_title + : R.string.personal_apps_suspended_title); final Notification notification = new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN) .setSmallIcon(android.R.drawable.stat_sys_warning) .setOngoing(true) - .setContentTitle( - mContext.getString( - R.string.personal_apps_suspended_title)) + .setContentTitle(title) .setContentText(mContext.getString( - R.string.personal_apps_suspended_text, maxTimeOffDays)) + R.string.personal_apps_suspended_text, maxTimeOffDays)) .setColor(mContext.getColor(R.color.system_notification_accent_color)) .setContentIntent(pendingIntent) .build(); @@ -16086,7 +16120,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } mInjector.binderWithCleanCallingIdentity( - () -> updatePersonalAppSuspension(userId, mUserManager.isUserUnlocked())); + () -> updatePersonalAppsSuspension(userId, mUserManager.isUserUnlocked())); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_MANAGED_PROFILE_MAXIMUM_TIME_OFF) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PersonalAppsSuspensionHelper.java b/services/devicepolicy/java/com/android/server/devicepolicy/PersonalAppsSuspensionHelper.java index d9db17eba887..da716eaed82b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PersonalAppsSuspensionHelper.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PersonalAppsSuspensionHelper.java @@ -51,6 +51,10 @@ import java.util.Set; public class PersonalAppsSuspensionHelper { private static final String LOG_TAG = DevicePolicyManagerService.LOG_TAG; + // Flags to get all packages even if the user is still locked. + private static final int PACKAGE_QUERY_FLAGS = + PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; + private final Context mContext; private final PackageManager mPackageManager; @@ -67,7 +71,7 @@ public class PersonalAppsSuspensionHelper { */ String[] getPersonalAppsForSuspension() { final List<PackageInfo> installedPackageInfos = - mPackageManager.getInstalledPackages(0 /* flags */); + mPackageManager.getInstalledPackages(PACKAGE_QUERY_FLAGS); final Set<String> result = new ArraySet<>(); for (final PackageInfo packageInfo : installedPackageInfos) { final ApplicationInfo info = packageInfo.applicationInfo; @@ -97,7 +101,7 @@ public class PersonalAppsSuspensionHelper { final Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); final List<ResolveInfo> matchingActivities = - mPackageManager.queryIntentActivities(intent, 0); + mPackageManager.queryIntentActivities(intent, PACKAGE_QUERY_FLAGS); for (final ResolveInfo resolveInfo : matchingActivities) { if (resolveInfo.activityInfo == null || TextUtils.isEmpty(resolveInfo.activityInfo.packageName)) { @@ -107,7 +111,7 @@ public class PersonalAppsSuspensionHelper { final String packageName = resolveInfo.activityInfo.packageName; try { final ApplicationInfo applicationInfo = - mPackageManager.getApplicationInfo(packageName, 0); + mPackageManager.getApplicationInfo(packageName, PACKAGE_QUERY_FLAGS); if (applicationInfo.isSystemApp() || applicationInfo.isUpdatedSystemApp()) { result.add(packageName); } @@ -147,7 +151,8 @@ public class PersonalAppsSuspensionHelper { private String getSettingsPackageName() { final Intent intent = new Intent(Settings.ACTION_SETTINGS); intent.addCategory(Intent.CATEGORY_DEFAULT); - final ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, /* flags= */ 0); + final ResolveInfo resolveInfo = + mPackageManager.resolveActivity(intent, PACKAGE_QUERY_FLAGS); if (resolveInfo != null) { return resolveInfo.activityInfo.packageName; } @@ -164,7 +169,7 @@ public class PersonalAppsSuspensionHelper { intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER); intentToResolve.setPackage(packageName); final List<ResolveInfo> resolveInfos = - mPackageManager.queryIntentActivities(intentToResolve, /* flags= */ 0); + mPackageManager.queryIntentActivities(intentToResolve, PACKAGE_QUERY_FLAGS); return resolveInfos != null && !resolveInfos.isEmpty(); } diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp index b13d33054e19..de639c5d0760 100644 --- a/services/incremental/Android.bp +++ b/services/incremental/Android.bp @@ -19,6 +19,21 @@ cc_defaults { proto: { type: "lite", }, + tidy: true, + tidy_checks: [ + "android-*", + "cert-*", + "clang-analyzer-security*", + "-cert-err34-c", + "clang-analyzer-security*", + // Disabling due to many unavoidable warnings from POSIX API usage. + "-google-runtime-int", + "-google-explicit-constructor", + // do not define variadic C function - JNI headers + "-cert-dcl50-cpp", + // operator=() does not handle self-assignment properly - all protobuf-generated classes + "-cert-oop54-cpp", + ], } cc_defaults { @@ -62,6 +77,7 @@ filegroup { srcs: [ "incremental_service.c", "IncrementalService.cpp", + "IncrementalServiceValidation.cpp", "BinderIncrementalService.cpp", "path.cpp", "ServiceWrappers.cpp", diff --git a/services/incremental/BinderIncrementalService.cpp b/services/incremental/BinderIncrementalService.cpp index fc8c6feac22b..847667427593 100644 --- a/services/incremental/BinderIncrementalService.cpp +++ b/services/incremental/BinderIncrementalService.cpp @@ -18,6 +18,7 @@ #include <android-base/logging.h> #include <android-base/no_destructor.h> +#include <android/os/IVold.h> #include <binder/IResultReceiver.h> #include <binder/PermissionCache.h> #include <incfs.h> @@ -117,11 +118,12 @@ binder::Status BinderIncrementalService::openStorage(const std::string& path, } binder::Status BinderIncrementalService::createStorage( - const std::string& path, const DataLoaderParamsParcel& params, + const std::string& path, const content::pm::DataLoaderParamsParcel& params, const ::android::sp<::android::content::pm::IDataLoaderStatusListener>& listener, int32_t createMode, int32_t* _aidl_return) { *_aidl_return = - mImpl.createStorage(path, const_cast<DataLoaderParamsParcel&&>(params), listener, + mImpl.createStorage(path, const_cast<content::pm::DataLoaderParamsParcel&&>(params), + listener, android::incremental::IncrementalService::CreateOptions( createMode)); return ok(); @@ -238,11 +240,8 @@ binder::Status BinderIncrementalService::isFileRangeLoaded(int32_t storageId, binder::Status BinderIncrementalService::getMetadataByPath(int32_t storageId, const std::string& path, std::vector<uint8_t>* _aidl_return) { - auto fid = mImpl.nodeFor(storageId, path); - if (fid != kIncFsInvalidFileId) { - auto metadata = mImpl.getMetadata(storageId, fid); - _aidl_return->assign(metadata.begin(), metadata.end()); - } + auto metadata = mImpl.getMetadata(storageId, path); + _aidl_return->assign(metadata.begin(), metadata.end()); return ok(); } diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp index f423119d240a..a1b4f2442153 100644 --- a/services/incremental/IncrementalService.cpp +++ b/services/incremental/IncrementalService.cpp @@ -18,32 +18,26 @@ #include "IncrementalService.h" -#include <android-base/file.h> #include <android-base/logging.h> #include <android-base/no_destructor.h> #include <android-base/properties.h> #include <android-base/stringprintf.h> -#include <android-base/strings.h> -#include <android/content/pm/IDataLoaderStatusListener.h> -#include <android/os/IVold.h> -#include <binder/BinderService.h> +#include <binder/AppOpsManager.h> #include <binder/Nullable.h> -#include <binder/ParcelFileDescriptor.h> #include <binder/Status.h> #include <sys/stat.h> #include <uuid/uuid.h> #include <charconv> #include <ctime> -#include <filesystem> #include <iterator> #include <span> #include <type_traits> +#include "IncrementalServiceValidation.h" #include "Metadata.pb.h" using namespace std::literals; -using namespace android::content::pm; namespace fs = std::filesystem; constexpr const char* kDataUsageStats = "android.permission.LOADER_USAGE_STATS"; @@ -51,10 +45,13 @@ constexpr const char* kOpUsage = "android:loader_usage_stats"; namespace android::incremental { +using content::pm::DataLoaderParamsParcel; +using content::pm::FileSystemControlParcel; +using content::pm::IDataLoader; + namespace { -using IncrementalFileSystemControlParcel = - ::android::os::incremental::IncrementalFileSystemControlParcel; +using IncrementalFileSystemControlParcel = os::incremental::IncrementalFileSystemControlParcel; struct Constants { static constexpr auto backing = "backing_store"sv; @@ -105,10 +102,13 @@ static std::string toMountKey(std::string_view path) { if (path::isAbsolute(path)) { path.remove_prefix(1); } + if (path.size() > 16) { + path = path.substr(0, 16); + } std::string res(path); - std::replace(res.begin(), res.end(), '/', '_'); - std::replace(res.begin(), res.end(), '@', '_'); - return std::string(constants().mountKeyPrefix) + res; + std::replace_if( + res.begin(), res.end(), [](char c) { return c == '/' || c == '@'; }, '_'); + return std::string(constants().mountKeyPrefix) += res; } static std::pair<std::string, std::string> makeMountDir(std::string_view incrementalDir, @@ -125,8 +125,26 @@ static std::pair<std::string, std::string> makeMountDir(std::string_view increme return {}; } +template <class Map> +typename Map::const_iterator findParentPath(const Map& map, std::string_view path) { + const auto nextIt = map.upper_bound(path); + if (nextIt == map.begin()) { + return map.end(); + } + const auto suspectIt = std::prev(nextIt); + if (!path::startsWith(path, suspectIt->first)) { + return map.end(); + } + return suspectIt; +} + +static base::unique_fd dup(base::borrowed_fd fd) { + const auto res = fcntl(fd.get(), F_DUPFD_CLOEXEC, 0); + return base::unique_fd(res); +} + template <class ProtoMessage, class Control> -static ProtoMessage parseFromIncfs(const IncFsWrapper* incfs, Control&& control, +static ProtoMessage parseFromIncfs(const IncFsWrapper* incfs, const Control& control, std::string_view path) { auto md = incfs->getMetadata(control, path); ProtoMessage message; @@ -155,20 +173,18 @@ std::string makeBindMdName() { } } // namespace -const bool IncrementalService::sEnablePerfLogging = - android::base::GetBoolProperty("incremental.perflogging", false); - IncrementalService::IncFsMount::~IncFsMount() { if (dataLoaderStub) { dataLoaderStub->cleanupResources(); dataLoaderStub = {}; } + control.close(); LOG(INFO) << "Unmounting and cleaning up mount " << mountId << " with root '" << root << '\''; for (auto&& [target, _] : bindPoints) { - LOG(INFO) << "\tbind: " << target; + LOG(INFO) << " bind: " << target; incrementalService.mVold->unmountIncFs(target); } - LOG(INFO) << "\troot: " << root; + LOG(INFO) << " root: " << root; incrementalService.mVold->unmountIncFs(path::join(root, constants().mount)); cleanupFilesystem(root); } @@ -193,8 +209,19 @@ auto IncrementalService::IncFsMount::makeStorage(StorageId id) -> StorageMap::it return storages.end(); } -static std::unique_ptr<DIR, decltype(&::closedir)> openDir(const char* path) { - return {::opendir(path), ::closedir}; +template <class Func> +static auto makeCleanup(Func&& f) { + auto deleter = [f = std::move(f)](auto) { f(); }; + // &f is a dangling pointer here, but we actually never use it as deleter moves it in. + return std::unique_ptr<Func, decltype(deleter)>(&f, std::move(deleter)); +} + +static std::unique_ptr<DIR, decltype(&::closedir)> openDir(const char* dir) { + return {::opendir(dir), ::closedir}; +} + +static auto openDir(std::string_view dir) { + return openDir(path::c_str(dir)); } static int rmDirContent(const char* path) { @@ -206,7 +233,7 @@ static int rmDirContent(const char* path) { if (entry->d_name == "."sv || entry->d_name == ".."sv) { continue; } - auto fullPath = android::base::StringPrintf("%s/%s", path, entry->d_name); + auto fullPath = base::StringPrintf("%s/%s", path, entry->d_name); if (entry->d_type == DT_DIR) { if (const auto err = rmDirContent(fullPath.c_str()); err != 0) { PLOG(WARNING) << "Failed to delete " << fullPath << " content"; @@ -256,7 +283,8 @@ IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_v runJobProcessing(); }); - mountExistingImages(); + const auto mountedRootNames = adoptMountedInstances(); + mountExistingImages(mountedRootNames); } IncrementalService::~IncrementalService() { @@ -268,15 +296,7 @@ IncrementalService::~IncrementalService() { mJobProcessor.join(); } -inline const char* toString(TimePoint t) { - using SystemClock = std::chrono::system_clock; - time_t time = SystemClock::to_time_t( - SystemClock::now() + - std::chrono::duration_cast<SystemClock::duration>(t - Clock::now())); - return std::ctime(&time); -} - -inline const char* toString(IncrementalService::BindKind kind) { +static const char* toString(IncrementalService::BindKind kind) { switch (kind) { case IncrementalService::BindKind::Temporary: return "Temporary"; @@ -291,38 +311,48 @@ void IncrementalService::onDump(int fd) { std::unique_lock l(mLock); - dprintf(fd, "Mounts (%d):\n", int(mMounts.size())); + dprintf(fd, "Mounts (%d): {\n", int(mMounts.size())); for (auto&& [id, ifs] : mMounts) { - const IncFsMount& mnt = *ifs.get(); - dprintf(fd, "\t[%d]:\n", id); - dprintf(fd, "\t\tmountId: %d\n", mnt.mountId); - dprintf(fd, "\t\troot: %s\n", mnt.root.c_str()); - dprintf(fd, "\t\tnextStorageDirNo: %d\n", mnt.nextStorageDirNo.load()); - if (mnt.dataLoaderStub) { - mnt.dataLoaderStub->onDump(fd); - } - dprintf(fd, "\t\tstorages (%d):\n", int(mnt.storages.size())); - for (auto&& [storageId, storage] : mnt.storages) { - dprintf(fd, "\t\t\t[%d] -> [%s]\n", storageId, storage.name.c_str()); - } - - dprintf(fd, "\t\tbindPoints (%d):\n", int(mnt.bindPoints.size())); - for (auto&& [target, bind] : mnt.bindPoints) { - dprintf(fd, "\t\t\t[%s]->[%d]:\n", target.c_str(), bind.storage); - dprintf(fd, "\t\t\t\tsavedFilename: %s\n", bind.savedFilename.c_str()); - dprintf(fd, "\t\t\t\tsourceDir: %s\n", bind.sourceDir.c_str()); - dprintf(fd, "\t\t\t\tkind: %s\n", toString(bind.kind)); + const IncFsMount& mnt = *ifs; + dprintf(fd, " [%d]: {\n", id); + if (id != mnt.mountId) { + dprintf(fd, " reference to mountId: %d\n", mnt.mountId); + } else { + dprintf(fd, " mountId: %d\n", mnt.mountId); + dprintf(fd, " root: %s\n", mnt.root.c_str()); + dprintf(fd, " nextStorageDirNo: %d\n", mnt.nextStorageDirNo.load()); + if (mnt.dataLoaderStub) { + mnt.dataLoaderStub->onDump(fd); + } else { + dprintf(fd, " dataLoader: null\n"); + } + dprintf(fd, " storages (%d): {\n", int(mnt.storages.size())); + for (auto&& [storageId, storage] : mnt.storages) { + dprintf(fd, " [%d] -> [%s]\n", storageId, storage.name.c_str()); + } + dprintf(fd, " }\n"); + + dprintf(fd, " bindPoints (%d): {\n", int(mnt.bindPoints.size())); + for (auto&& [target, bind] : mnt.bindPoints) { + dprintf(fd, " [%s]->[%d]:\n", target.c_str(), bind.storage); + dprintf(fd, " savedFilename: %s\n", bind.savedFilename.c_str()); + dprintf(fd, " sourceDir: %s\n", bind.sourceDir.c_str()); + dprintf(fd, " kind: %s\n", toString(bind.kind)); + } + dprintf(fd, " }\n"); } + dprintf(fd, " }\n"); } - - dprintf(fd, "Sorted binds (%d):\n", int(mBindsByPath.size())); + dprintf(fd, "}\n"); + dprintf(fd, "Sorted binds (%d): {\n", int(mBindsByPath.size())); for (auto&& [target, mountPairIt] : mBindsByPath) { const auto& bind = mountPairIt->second; - dprintf(fd, "\t\t[%s]->[%d]:\n", target.c_str(), bind.storage); - dprintf(fd, "\t\t\tsavedFilename: %s\n", bind.savedFilename.c_str()); - dprintf(fd, "\t\t\tsourceDir: %s\n", bind.sourceDir.c_str()); - dprintf(fd, "\t\t\tkind: %s\n", toString(bind.kind)); + dprintf(fd, " [%s]->[%d]:\n", target.c_str(), bind.storage); + dprintf(fd, " savedFilename: %s\n", bind.savedFilename.c_str()); + dprintf(fd, " sourceDir: %s\n", bind.sourceDir.c_str()); + dprintf(fd, " kind: %s\n", toString(bind.kind)); } + dprintf(fd, "}\n"); } void IncrementalService::onSystemReady() { @@ -471,9 +501,9 @@ StorageId IncrementalService::createStorage( metadata::Mount m; m.mutable_storage()->set_id(ifs->mountId); m.mutable_loader()->set_type((int)dataLoaderParams.type); - m.mutable_loader()->set_package_name(dataLoaderParams.packageName); - m.mutable_loader()->set_class_name(dataLoaderParams.className); - m.mutable_loader()->set_arguments(dataLoaderParams.arguments); + m.mutable_loader()->set_allocated_package_name(&dataLoaderParams.packageName); + m.mutable_loader()->set_allocated_class_name(&dataLoaderParams.className); + m.mutable_loader()->set_allocated_arguments(&dataLoaderParams.arguments); const auto metadata = m.SerializeAsString(); m.mutable_loader()->release_arguments(); m.mutable_loader()->release_class_name(); @@ -528,7 +558,7 @@ StorageId IncrementalService::createLinkedStorage(std::string_view mountPoint, } std::unique_lock l(mLock); - const auto& ifs = getIfsLocked(linkedStorage); + auto ifs = getIfsLocked(linkedStorage); if (!ifs) { LOG(ERROR) << "Ifs unavailable"; return kInvalidStorageId; @@ -552,6 +582,8 @@ StorageId IncrementalService::createLinkedStorage(std::string_view mountPoint, bk, l); err < 0) { LOG(ERROR) << "bindMount failed with error: " << err; + (void)mIncFs->unlink(ifs->control, storageIt->second.name); + ifs->storages.erase(storageIt); return kInvalidStorageId; } @@ -561,15 +593,7 @@ StorageId IncrementalService::createLinkedStorage(std::string_view mountPoint, IncrementalService::BindPathMap::const_iterator IncrementalService::findStorageLocked( std::string_view path) const { - auto bindPointIt = mBindsByPath.upper_bound(path); - if (bindPointIt == mBindsByPath.begin()) { - return mBindsByPath.end(); - } - --bindPointIt; - if (!path::startsWith(path, bindPointIt->first)) { - return mBindsByPath.end(); - } - return bindPointIt; + return findParentPath(mBindsByPath, path); } StorageId IncrementalService::findStorageId(std::string_view path) const { @@ -611,13 +635,12 @@ int IncrementalService::setStorageParams(StorageId storageId, bool enableReadLog } binder::Status IncrementalService::applyStorageParams(IncFsMount& ifs, bool enableReadLogs) { - using unique_fd = ::android::base::unique_fd; - ::android::os::incremental::IncrementalFileSystemControlParcel control; - control.cmd.reset(unique_fd(dup(ifs.control.cmd()))); - control.pendingReads.reset(unique_fd(dup(ifs.control.pendingReads()))); + os::incremental::IncrementalFileSystemControlParcel control; + control.cmd.reset(dup(ifs.control.cmd())); + control.pendingReads.reset(dup(ifs.control.pendingReads())); auto logsFd = ifs.control.logs(); if (logsFd >= 0) { - control.log.reset(unique_fd(dup(logsFd))); + control.log.reset(dup(logsFd)); } std::lock_guard l(mMountOperationLock); @@ -664,38 +687,6 @@ StorageId IncrementalService::openStorage(std::string_view pathInMount) { return findStorageId(path::normalize(pathInMount)); } -FileId IncrementalService::nodeFor(StorageId storage, std::string_view subpath) const { - const auto ifs = getIfs(storage); - if (!ifs) { - return kIncFsInvalidFileId; - } - std::unique_lock l(ifs->lock); - auto storageIt = ifs->storages.find(storage); - if (storageIt == ifs->storages.end()) { - return kIncFsInvalidFileId; - } - if (subpath.empty() || subpath == "."sv) { - return kIncFsInvalidFileId; - } - auto path = path::join(ifs->root, constants().mount, storageIt->second.name, subpath); - l.unlock(); - return mIncFs->getFileId(ifs->control, path); -} - -std::pair<FileId, std::string_view> IncrementalService::parentAndNameFor( - StorageId storage, std::string_view subpath) const { - auto name = path::basename(subpath); - if (name.empty()) { - return {kIncFsInvalidFileId, {}}; - } - auto dir = path::dirname(subpath); - if (dir.empty() || dir == "/"sv) { - return {kIncFsInvalidFileId, {}}; - } - auto id = nodeFor(storage, dir); - return {id, name}; -} - IncrementalService::IfsMountPtr IncrementalService::getIfs(StorageId storage) const { std::lock_guard l(mLock); return getIfsLocked(storage); @@ -704,7 +695,7 @@ IncrementalService::IfsMountPtr IncrementalService::getIfs(StorageId storage) co const IncrementalService::IfsMountPtr& IncrementalService::getIfsLocked(StorageId storage) const { auto it = mMounts.find(storage); if (it == mMounts.end()) { - static const android::base::NoDestructor<IfsMountPtr> kEmpty{}; + static const base::NoDestructor<IfsMountPtr> kEmpty{}; return *kEmpty; } return it->second; @@ -713,21 +704,25 @@ const IncrementalService::IfsMountPtr& IncrementalService::getIfsLocked(StorageI int IncrementalService::bind(StorageId storage, std::string_view source, std::string_view target, BindKind kind) { if (!isValidMountTarget(target)) { + LOG(ERROR) << __func__ << ": not a valid bind target " << target; return -EINVAL; } const auto ifs = getIfs(storage); if (!ifs) { + LOG(ERROR) << __func__ << ": no ifs object for storage " << storage; return -EINVAL; } std::unique_lock l(ifs->lock); const auto storageInfo = ifs->storages.find(storage); if (storageInfo == ifs->storages.end()) { + LOG(ERROR) << "no storage"; return -EINVAL; } - std::string normSource = normalizePathToStorageLocked(storageInfo, source); + std::string normSource = normalizePathToStorageLocked(*ifs, storageInfo, source); if (normSource.empty()) { + LOG(ERROR) << "invalid source path"; return -EINVAL; } l.unlock(); @@ -779,33 +774,37 @@ int IncrementalService::unbind(StorageId storage, std::string_view target) { } std::string IncrementalService::normalizePathToStorageLocked( - IncFsMount::StorageMap::iterator storageIt, std::string_view path) { - std::string normPath; - if (path::isAbsolute(path)) { - normPath = path::normalize(path); - if (!path::startsWith(normPath, storageIt->second.name)) { - return {}; - } - } else { - normPath = path::normalize(path::join(storageIt->second.name, path)); + const IncFsMount& incfs, IncFsMount::StorageMap::const_iterator storageIt, + std::string_view path) const { + if (!path::isAbsolute(path)) { + return path::normalize(path::join(storageIt->second.name, path)); + } + auto normPath = path::normalize(path); + if (path::startsWith(normPath, storageIt->second.name)) { + return normPath; + } + // not that easy: need to find if any of the bind points match + const auto bindIt = findParentPath(incfs.bindPoints, normPath); + if (bindIt == incfs.bindPoints.end()) { + return {}; } - return normPath; + return path::join(bindIt->second.sourceDir, path::relativize(bindIt->first, normPath)); } -std::string IncrementalService::normalizePathToStorage(const IncrementalService::IfsMountPtr& ifs, - StorageId storage, std::string_view path) { - std::unique_lock l(ifs->lock); - const auto storageInfo = ifs->storages.find(storage); - if (storageInfo == ifs->storages.end()) { +std::string IncrementalService::normalizePathToStorage(const IncFsMount& ifs, StorageId storage, + std::string_view path) const { + std::unique_lock l(ifs.lock); + const auto storageInfo = ifs.storages.find(storage); + if (storageInfo == ifs.storages.end()) { return {}; } - return normalizePathToStorageLocked(storageInfo, path); + return normalizePathToStorageLocked(ifs, storageInfo, path); } int IncrementalService::makeFile(StorageId storage, std::string_view path, int mode, FileId id, incfs::NewFileParams params) { if (auto ifs = getIfs(storage)) { - std::string normPath = normalizePathToStorage(ifs, storage, path); + std::string normPath = normalizePathToStorage(*ifs, storage, path); if (normPath.empty()) { LOG(ERROR) << "Internal error: storageId " << storage << " failed to normalize: " << path; @@ -823,7 +822,7 @@ int IncrementalService::makeFile(StorageId storage, std::string_view path, int m int IncrementalService::makeDir(StorageId storageId, std::string_view path, int mode) { if (auto ifs = getIfs(storageId)) { - std::string normPath = normalizePathToStorage(ifs, storageId, path); + std::string normPath = normalizePathToStorage(*ifs, storageId, path); if (normPath.empty()) { return -EINVAL; } @@ -837,40 +836,41 @@ int IncrementalService::makeDirs(StorageId storageId, std::string_view path, int if (!ifs) { return -EINVAL; } + return makeDirs(*ifs, storageId, path, mode); +} + +int IncrementalService::makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, + int mode) { std::string normPath = normalizePathToStorage(ifs, storageId, path); if (normPath.empty()) { return -EINVAL; } - auto err = mIncFs->makeDir(ifs->control, normPath, mode); - if (err == -EEXIST) { - return 0; - } else if (err != -ENOENT) { - return err; - } - if (auto err = makeDirs(storageId, path::dirname(normPath), mode)) { - return err; - } - return mIncFs->makeDir(ifs->control, normPath, mode); + return mIncFs->makeDirs(ifs.control, normPath, mode); } int IncrementalService::link(StorageId sourceStorageId, std::string_view oldPath, StorageId destStorageId, std::string_view newPath) { - auto ifsSrc = getIfs(sourceStorageId); - auto ifsDest = sourceStorageId == destStorageId ? ifsSrc : getIfs(destStorageId); - if (ifsSrc && ifsSrc == ifsDest) { - std::string normOldPath = normalizePathToStorage(ifsSrc, sourceStorageId, oldPath); - std::string normNewPath = normalizePathToStorage(ifsDest, destStorageId, newPath); - if (normOldPath.empty() || normNewPath.empty()) { - return -EINVAL; - } - return mIncFs->link(ifsSrc->control, normOldPath, normNewPath); + std::unique_lock l(mLock); + auto ifsSrc = getIfsLocked(sourceStorageId); + if (!ifsSrc) { + return -EINVAL; } - return -EINVAL; + if (sourceStorageId != destStorageId && getIfsLocked(destStorageId) != ifsSrc) { + return -EINVAL; + } + l.unlock(); + std::string normOldPath = normalizePathToStorage(*ifsSrc, sourceStorageId, oldPath); + std::string normNewPath = normalizePathToStorage(*ifsSrc, destStorageId, newPath); + if (normOldPath.empty() || normNewPath.empty()) { + LOG(ERROR) << "Invalid paths in link(): " << normOldPath << " | " << normNewPath; + return -EINVAL; + } + return mIncFs->link(ifsSrc->control, normOldPath, normNewPath); } int IncrementalService::unlink(StorageId storage, std::string_view path) { if (auto ifs = getIfs(storage)) { - std::string normOldPath = normalizePathToStorage(ifs, storage, path); + std::string normOldPath = normalizePathToStorage(*ifs, storage, path); return mIncFs->unlink(ifs->control, normOldPath); } return -EINVAL; @@ -881,10 +881,12 @@ int IncrementalService::addBindMount(IncFsMount& ifs, StorageId storage, std::string&& target, BindKind kind, std::unique_lock<std::mutex>& mainLock) { if (!isValidMountTarget(target)) { + LOG(ERROR) << __func__ << ": invalid mount target " << target; return -EINVAL; } std::string mdFileName; + std::string metadataFullPath; if (kind != BindKind::Temporary) { metadata::BindPoint bp; bp.set_storage_id(storage); @@ -894,17 +896,21 @@ int IncrementalService::addBindMount(IncFsMount& ifs, StorageId storage, bp.release_dest_path(); bp.release_source_subdir(); mdFileName = makeBindMdName(); - auto node = - mIncFs->makeFile(ifs.control, path::join(ifs.root, constants().mount, mdFileName), - 0444, idFromMetadata(metadata), - {.metadata = {metadata.data(), (IncFsSize)metadata.size()}}); + metadataFullPath = path::join(ifs.root, constants().mount, mdFileName); + auto node = mIncFs->makeFile(ifs.control, metadataFullPath, 0444, idFromMetadata(metadata), + {.metadata = {metadata.data(), (IncFsSize)metadata.size()}}); if (node) { + LOG(ERROR) << __func__ << ": couldn't create a mount node " << mdFileName; return int(node); } } - return addBindMountWithMd(ifs, storage, std::move(mdFileName), std::move(source), - std::move(target), kind, mainLock); + const auto res = addBindMountWithMd(ifs, storage, std::move(mdFileName), std::move(source), + std::move(target), kind, mainLock); + if (res) { + mIncFs->unlink(ifs.control, metadataFullPath); + } + return res; } int IncrementalService::addBindMountWithMd(IncrementalService::IncFsMount& ifs, StorageId storage, @@ -929,61 +935,39 @@ int IncrementalService::addBindMountWithMd(IncrementalService::IncFsMount& ifs, mainLock.lock(); } std::lock_guard l(ifs.lock); + addBindMountRecordLocked(ifs, storage, std::move(metadataName), std::move(source), + std::move(target), kind); + return 0; +} + +void IncrementalService::addBindMountRecordLocked(IncFsMount& ifs, StorageId storage, + std::string&& metadataName, std::string&& source, + std::string&& target, BindKind kind) { const auto [it, _] = ifs.bindPoints.insert_or_assign(target, IncFsMount::Bind{storage, std::move(metadataName), std::move(source), kind}); mBindsByPath[std::move(target)] = it; - return 0; } -RawMetadata IncrementalService::getMetadata(StorageId storage, FileId node) const { +RawMetadata IncrementalService::getMetadata(StorageId storage, std::string_view path) const { const auto ifs = getIfs(storage); if (!ifs) { return {}; } - return mIncFs->getMetadata(ifs->control, node); + const auto normPath = normalizePathToStorage(*ifs, storage, path); + if (normPath.empty()) { + return {}; + } + return mIncFs->getMetadata(ifs->control, normPath); } -std::vector<std::string> IncrementalService::listFiles(StorageId storage) const { +RawMetadata IncrementalService::getMetadata(StorageId storage, FileId node) const { const auto ifs = getIfs(storage); if (!ifs) { return {}; } - - std::unique_lock l(ifs->lock); - auto subdirIt = ifs->storages.find(storage); - if (subdirIt == ifs->storages.end()) { - return {}; - } - auto dir = path::join(ifs->root, constants().mount, subdirIt->second.name); - l.unlock(); - - const auto prefixSize = dir.size() + 1; - std::vector<std::string> todoDirs{std::move(dir)}; - std::vector<std::string> result; - do { - auto currDir = std::move(todoDirs.back()); - todoDirs.pop_back(); - - auto d = - std::unique_ptr<DIR, decltype(&::closedir)>(::opendir(currDir.c_str()), ::closedir); - while (auto e = ::readdir(d.get())) { - if (e->d_type == DT_REG) { - result.emplace_back( - path::join(std::string_view(currDir).substr(prefixSize), e->d_name)); - continue; - } - if (e->d_type == DT_DIR) { - if (e->d_name == "."sv || e->d_name == ".."sv) { - continue; - } - todoDirs.emplace_back(path::join(currDir, e->d_name)); - continue; - } - } - } while (!todoDirs.empty()); - return result; + return mIncFs->getMetadata(ifs->control, node); } bool IncrementalService::startLoading(StorageId storage) const { @@ -1003,16 +987,216 @@ bool IncrementalService::startLoading(StorageId storage) const { return true; } -void IncrementalService::mountExistingImages() { - for (const auto& entry : fs::directory_iterator(mIncrementalDir)) { - const auto path = entry.path().u8string(); - const auto name = entry.path().filename().u8string(); - if (!base::StartsWith(name, constants().mountKeyPrefix)) { +std::unordered_set<std::string_view> IncrementalService::adoptMountedInstances() { + std::unordered_set<std::string_view> mountedRootNames; + mIncFs->listExistingMounts([this, &mountedRootNames](auto root, auto backingDir, auto binds) { + LOG(INFO) << "Existing mount: " << backingDir << "->" << root; + for (auto [source, target] : binds) { + LOG(INFO) << " bind: '" << source << "'->'" << target << "'"; + LOG(INFO) << " " << path::join(root, source); + } + + // Ensure it's a kind of a mount that's managed by IncrementalService + if (path::basename(root) != constants().mount || + path::basename(backingDir) != constants().backing) { + return; + } + const auto expectedRoot = path::dirname(root); + if (path::dirname(backingDir) != expectedRoot) { + return; + } + if (path::dirname(expectedRoot) != mIncrementalDir) { + return; + } + if (!path::basename(expectedRoot).starts_with(constants().mountKeyPrefix)) { + return; + } + + LOG(INFO) << "Looks like an IncrementalService-owned: " << expectedRoot; + + // make sure we clean up the mount if it happens to be a bad one. + // Note: unmounting needs to run first, so the cleanup object is created _last_. + auto cleanupFiles = makeCleanup([&]() { + LOG(INFO) << "Failed to adopt existing mount, deleting files: " << expectedRoot; + IncFsMount::cleanupFilesystem(expectedRoot); + }); + auto cleanupMounts = makeCleanup([&]() { + LOG(INFO) << "Failed to adopt existing mount, cleaning up: " << expectedRoot; + for (auto&& [_, target] : binds) { + mVold->unmountIncFs(std::string(target)); + } + mVold->unmountIncFs(std::string(root)); + }); + + auto control = mIncFs->openMount(root); + if (!control) { + LOG(INFO) << "failed to open mount " << root; + return; + } + + auto mountRecord = + parseFromIncfs<metadata::Mount>(mIncFs.get(), control, + path::join(root, constants().infoMdName)); + if (!mountRecord.has_loader() || !mountRecord.has_storage()) { + LOG(ERROR) << "Bad mount metadata in mount at " << expectedRoot; + return; + } + + auto mountId = mountRecord.storage().id(); + mNextId = std::max(mNextId, mountId + 1); + + DataLoaderParamsParcel dataLoaderParams; + { + const auto& loader = mountRecord.loader(); + dataLoaderParams.type = (content::pm::DataLoaderType)loader.type(); + dataLoaderParams.packageName = loader.package_name(); + dataLoaderParams.className = loader.class_name(); + dataLoaderParams.arguments = loader.arguments(); + } + + auto ifs = std::make_shared<IncFsMount>(std::string(expectedRoot), mountId, + std::move(control), *this); + cleanupFiles.release(); // ifs will take care of that now + + std::vector<std::pair<std::string, metadata::BindPoint>> permanentBindPoints; + auto d = openDir(root); + while (auto e = ::readdir(d.get())) { + if (e->d_type == DT_REG) { + auto name = std::string_view(e->d_name); + if (name.starts_with(constants().mountpointMdPrefix)) { + permanentBindPoints + .emplace_back(name, + parseFromIncfs<metadata::BindPoint>(mIncFs.get(), + ifs->control, + path::join(root, + name))); + if (permanentBindPoints.back().second.dest_path().empty() || + permanentBindPoints.back().second.source_subdir().empty()) { + permanentBindPoints.pop_back(); + mIncFs->unlink(ifs->control, path::join(root, name)); + } else { + LOG(INFO) << "Permanent bind record: '" + << permanentBindPoints.back().second.source_subdir() << "'->'" + << permanentBindPoints.back().second.dest_path() << "'"; + } + } + } else if (e->d_type == DT_DIR) { + if (e->d_name == "."sv || e->d_name == ".."sv) { + continue; + } + auto name = std::string_view(e->d_name); + if (name.starts_with(constants().storagePrefix)) { + int storageId; + const auto res = + std::from_chars(name.data() + constants().storagePrefix.size() + 1, + name.data() + name.size(), storageId); + if (res.ec != std::errc{} || *res.ptr != '_') { + LOG(WARNING) << "Ignoring storage with invalid name '" << name + << "' for mount " << expectedRoot; + continue; + } + auto [_, inserted] = mMounts.try_emplace(storageId, ifs); + if (!inserted) { + LOG(WARNING) << "Ignoring storage with duplicate id " << storageId + << " for mount " << expectedRoot; + continue; + } + ifs->storages.insert_or_assign(storageId, + IncFsMount::Storage{path::join(root, name)}); + mNextId = std::max(mNextId, storageId + 1); + } + } + } + + if (ifs->storages.empty()) { + LOG(WARNING) << "No valid storages in mount " << root; + return; + } + + // now match the mounted directories with what we expect to have in the metadata + { + std::unique_lock l(mLock, std::defer_lock); + for (auto&& [metadataFile, bindRecord] : permanentBindPoints) { + auto mountedIt = std::find_if(binds.begin(), binds.end(), + [&, bindRecord = bindRecord](auto&& bind) { + return bind.second == bindRecord.dest_path() && + path::join(root, bind.first) == + bindRecord.source_subdir(); + }); + if (mountedIt != binds.end()) { + LOG(INFO) << "Matched permanent bound " << bindRecord.source_subdir() + << " to mount " << mountedIt->first; + addBindMountRecordLocked(*ifs, bindRecord.storage_id(), std::move(metadataFile), + std::move(*bindRecord.mutable_source_subdir()), + std::move(*bindRecord.mutable_dest_path()), + BindKind::Permanent); + if (mountedIt != binds.end() - 1) { + std::iter_swap(mountedIt, binds.end() - 1); + } + binds = binds.first(binds.size() - 1); + } else { + LOG(INFO) << "Didn't match permanent bound " << bindRecord.source_subdir() + << ", mounting"; + // doesn't exist - try mounting back + if (addBindMountWithMd(*ifs, bindRecord.storage_id(), std::move(metadataFile), + std::move(*bindRecord.mutable_source_subdir()), + std::move(*bindRecord.mutable_dest_path()), + BindKind::Permanent, l)) { + mIncFs->unlink(ifs->control, metadataFile); + } + } + } + } + + // if anything stays in |binds| those are probably temporary binds; system restarted since + // they were mounted - so let's unmount them all. + for (auto&& [source, target] : binds) { + if (source.empty()) { + continue; + } + mVold->unmountIncFs(std::string(target)); + } + cleanupMounts.release(); // ifs now manages everything + + if (ifs->bindPoints.empty()) { + LOG(WARNING) << "No valid bind points for mount " << expectedRoot; + deleteStorage(*ifs); + return; + } + + prepareDataLoaderLocked(*ifs, std::move(dataLoaderParams)); + CHECK(ifs->dataLoaderStub); + + mountedRootNames.insert(path::basename(ifs->root)); + + // not locking here at all: we're still in the constructor, no other calls can happen + mMounts[ifs->mountId] = std::move(ifs); + }); + + return mountedRootNames; +} + +void IncrementalService::mountExistingImages( + const std::unordered_set<std::string_view>& mountedRootNames) { + auto dir = openDir(mIncrementalDir); + if (!dir) { + PLOG(WARNING) << "Couldn't open the root incremental dir " << mIncrementalDir; + return; + } + while (auto entry = ::readdir(dir.get())) { + if (entry->d_type != DT_DIR) { + continue; + } + std::string_view name = entry->d_name; + if (!name.starts_with(constants().mountKeyPrefix)) { + continue; + } + if (mountedRootNames.find(name) != mountedRootNames.end()) { continue; } const auto root = path::join(mIncrementalDir, name); if (!mountExistingImage(root)) { - IncFsMount::cleanupFilesystem(path); + IncFsMount::cleanupFilesystem(root); } } } @@ -1049,7 +1233,7 @@ bool IncrementalService::mountExistingImage(std::string_view root) { DataLoaderParamsParcel dataLoaderParams; { const auto& loader = mount.loader(); - dataLoaderParams.type = (android::content::pm::DataLoaderType)loader.type(); + dataLoaderParams.type = (content::pm::DataLoaderType)loader.type(); dataLoaderParams.packageName = loader.package_name(); dataLoaderParams.className = loader.class_name(); dataLoaderParams.arguments = loader.arguments(); @@ -1059,7 +1243,7 @@ bool IncrementalService::mountExistingImage(std::string_view root) { CHECK(ifs->dataLoaderStub); std::vector<std::pair<std::string, metadata::BindPoint>> bindPoints; - auto d = openDir(path::c_str(mountTarget)); + auto d = openDir(mountTarget); while (auto e = ::readdir(d.get())) { if (e->d_type == DT_REG) { auto name = std::string_view(e->d_name); @@ -1109,12 +1293,14 @@ bool IncrementalService::mountExistingImage(std::string_view root) { } int bindCount = 0; - for (auto&& bp : bindPoints) { + { std::unique_lock l(mLock, std::defer_lock); - bindCount += !addBindMountWithMd(*ifs, bp.second.storage_id(), std::move(bp.first), - std::move(*bp.second.mutable_source_subdir()), - std::move(*bp.second.mutable_dest_path()), - BindKind::Permanent, l); + for (auto&& bp : bindPoints) { + bindCount += !addBindMountWithMd(*ifs, bp.second.storage_id(), std::move(bp.first), + std::move(*bp.second.mutable_source_subdir()), + std::move(*bp.second.mutable_dest_path()), + BindKind::Permanent, l); + } } if (bindCount == 0) { @@ -1123,30 +1309,35 @@ bool IncrementalService::mountExistingImage(std::string_view root) { return false; } + // not locking here at all: we're still in the constructor, no other calls can happen mMounts[ifs->mountId] = std::move(ifs); return true; } IncrementalService::DataLoaderStubPtr IncrementalService::prepareDataLoader( - IncrementalService::IncFsMount& ifs, DataLoaderParamsParcel&& params, + IncFsMount& ifs, DataLoaderParamsParcel&& params, const DataLoaderStatusListener* externalListener) { std::unique_lock l(ifs.lock); + prepareDataLoaderLocked(ifs, std::move(params), externalListener); + return ifs.dataLoaderStub; +} + +void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderParamsParcel&& params, + const DataLoaderStatusListener* externalListener) { if (ifs.dataLoaderStub) { LOG(INFO) << "Skipped data loader preparation because it already exists"; - return ifs.dataLoaderStub; + return; } FileSystemControlParcel fsControlParcel; fsControlParcel.incremental = aidl::make_nullable<IncrementalFileSystemControlParcel>(); - fsControlParcel.incremental->cmd.reset(base::unique_fd(::dup(ifs.control.cmd()))); - fsControlParcel.incremental->pendingReads.reset( - base::unique_fd(::dup(ifs.control.pendingReads()))); - fsControlParcel.incremental->log.reset(base::unique_fd(::dup(ifs.control.logs()))); + fsControlParcel.incremental->cmd.reset(dup(ifs.control.cmd())); + fsControlParcel.incremental->pendingReads.reset(dup(ifs.control.pendingReads())); + fsControlParcel.incremental->log.reset(dup(ifs.control.logs())); fsControlParcel.service = new IncrementalServiceConnector(*this, ifs.mountId); ifs.dataLoaderStub = new DataLoaderStub(*this, ifs.mountId, std::move(params), std::move(fsControlParcel), externalListener); - return ifs.dataLoaderStub; } template <class Duration> @@ -1167,7 +1358,7 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_ } // First prepare target directories if they don't exist yet - if (auto res = makeDirs(storage, libDirRelativePath, 0755)) { + if (auto res = makeDirs(*ifs, storage, libDirRelativePath, 0755)) { LOG(ERROR) << "Failed to prepare target lib directory " << libDirRelativePath << " errno: " << res; return false; @@ -1204,11 +1395,11 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_ auto startFileTs = Clock::now(); const auto libName = path::basename(fileName); - const auto targetLibPath = path::join(libDirRelativePath, libName); - const auto targetLibPathAbsolute = normalizePathToStorage(ifs, storage, targetLibPath); + auto targetLibPath = path::join(libDirRelativePath, libName); + const auto targetLibPathAbsolute = normalizePathToStorage(*ifs, storage, targetLibPath); // If the extract file already exists, skip if (access(targetLibPathAbsolute.c_str(), F_OK) == 0) { - if (sEnablePerfLogging) { + if (perfLoggingEnabled()) { LOG(INFO) << "incfs: Native lib file already exists: " << targetLibPath << "; skipping extraction, spent " << elapsedMcs(startFileTs, Clock::now()) << "mcs"; @@ -1235,7 +1426,7 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_ // If it is a zero-byte file, skip data writing if (entry.uncompressed_length == 0) { - if (sEnablePerfLogging) { + if (perfLoggingEnabled()) { LOG(INFO) << "incfs: Extracted " << libName << "(0 bytes): " << elapsedMcs(startFileTs, makeFileTs) << "mcs"; } @@ -1248,7 +1439,7 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_ extractZipFile(ifs.lock(), zipFile.get(), entry, libFileId, libPath, makeFileTs); }); - if (sEnablePerfLogging) { + if (perfLoggingEnabled()) { auto prepareJobTs = Clock::now(); LOG(INFO) << "incfs: Processed " << libName << ": " << elapsedMcs(startFileTs, prepareJobTs) @@ -1275,7 +1466,7 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_ mJobCondition.notify_all(); } - if (sEnablePerfLogging) { + if (perfLoggingEnabled()) { auto end = Clock::now(); LOG(INFO) << "incfs: configureNativeBinaries complete in " << elapsedMcs(start, end) << "mcs, make dirs: " << elapsedMcs(start, mkDirsTs) @@ -1340,7 +1531,7 @@ void IncrementalService::extractZipFile(const IfsMountPtr& ifs, ZipArchiveHandle return; } - if (sEnablePerfLogging) { + if (perfLoggingEnabled()) { auto endFileTs = Clock::now(); LOG(INFO) << "incfs: Extracted " << libName << "(" << entry.compressed_length << " -> " << entry.uncompressed_length << " bytes): " << elapsedMcs(startedTs, endFileTs) @@ -1356,7 +1547,7 @@ bool IncrementalService::waitForNativeBinariesExtraction(StorageId storage) { struct WaitPrinter { const Clock::time_point startTs = Clock::now(); ~WaitPrinter() noexcept { - if (sEnablePerfLogging) { + if (perfLoggingEnabled()) { const auto endTs = Clock::now(); LOG(INFO) << "incfs: waitForNativeBinariesExtraction() complete in " << elapsedMcs(startTs, endTs) << "mcs"; @@ -1381,6 +1572,11 @@ bool IncrementalService::waitForNativeBinariesExtraction(StorageId storage) { return mRunning; } +bool IncrementalService::perfLoggingEnabled() { + static const bool enabled = base::GetBoolProperty("incremental.perflogging", false); + return enabled; +} + void IncrementalService::runJobProcessing() { for (;;) { std::unique_lock lock(mJobMutex); @@ -1492,12 +1688,17 @@ bool IncrementalService::DataLoaderStub::requestDestroy() { return setTargetStatus(IDataLoaderStatusListener::DATA_LOADER_DESTROYED); } -bool IncrementalService::DataLoaderStub::setTargetStatus(int status) { +bool IncrementalService::DataLoaderStub::setTargetStatus(int newStatus) { + int oldStatus, curStatus; { std::unique_lock lock(mStatusMutex); - mTargetStatus = status; + oldStatus = mTargetStatus; + mTargetStatus = newStatus; mTargetStatusTs = Clock::now(); + curStatus = mCurrentStatus; } + LOG(DEBUG) << "Target status update for DataLoader " << mId << ": " << oldStatus << " -> " + << newStatus << " (current " << curStatus << ")"; return fsmStep(); } @@ -1508,12 +1709,30 @@ bool IncrementalService::DataLoaderStub::waitForStatus(int status, Clock::durati [this, status] { return mCurrentStatus == status; }); } +bool IncrementalService::DataLoaderStub::bind() { + bool result = false; + auto status = mService.mDataLoaderManager->bindToDataLoader(mId, mParams, this, &result); + if (!status.isOk() || !result) { + LOG(ERROR) << "Failed to bind a data loader for mount " << mId; + return false; + } + return true; +} + bool IncrementalService::DataLoaderStub::create() { - bool created = false; - auto status = mService.mDataLoaderManager->initializeDataLoader(mId, mParams, mControl, this, - &created); - if (!status.isOk() || !created) { - LOG(ERROR) << "Failed to create a data loader for mount " << mId; + sp<IDataLoader> dataloader; + auto status = mService.mDataLoaderManager->getDataLoader(mId, &dataloader); + if (!status.isOk()) { + LOG(ERROR) << "Failed to get dataloader: " << status.toString8(); + return false; + } + if (!dataloader) { + LOG(ERROR) << "DataLoader is null: " << status.toString8(); + return false; + } + status = dataloader->create(mId, mParams, mControl, this); + if (!status.isOk()) { + LOG(ERROR) << "Failed to start DataLoader: " << status.toString8(); return false; } return true; @@ -1539,7 +1758,7 @@ bool IncrementalService::DataLoaderStub::start() { } bool IncrementalService::DataLoaderStub::destroy() { - mService.mDataLoaderManager->destroyDataLoader(mId); + mService.mDataLoaderManager->unbindFromDataLoader(mId); return true; } @@ -1575,6 +1794,8 @@ bool IncrementalService::DataLoaderStub::fsmStep() { case IDataLoaderStatusListener::DATA_LOADER_CREATED: switch (currentStatus) { case IDataLoaderStatusListener::DATA_LOADER_DESTROYED: + return bind(); + case IDataLoaderStatusListener::DATA_LOADER_BOUND: return create(); } break; @@ -1596,14 +1817,20 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount return binder::Status::fromServiceSpecificError(-EPERM, "Mount ID mismatch."); } + int targetStatus, oldStatus; { std::unique_lock lock(mStatusMutex); if (mCurrentStatus == newStatus) { return binder::Status::ok(); } mCurrentStatus = newStatus; + oldStatus = mCurrentStatus; + targetStatus = mTargetStatus; } + LOG(DEBUG) << "Current status update for DataLoader " << mId << ": " << oldStatus << " -> " + << newStatus << " (target " << targetStatus << ")"; + if (mListener) { mListener->onStatusChanged(mountId, newStatus); } @@ -1616,17 +1843,19 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount } void IncrementalService::DataLoaderStub::onDump(int fd) { - dprintf(fd, "\t\tdataLoader:"); - dprintf(fd, "\t\t\tcurrentStatus: %d\n", mCurrentStatus); - dprintf(fd, "\t\t\ttargetStatus: %d\n", mTargetStatus); - dprintf(fd, "\t\t\ttargetStatusTs: %lldmcs\n", + dprintf(fd, " dataLoader: {\n"); + dprintf(fd, " currentStatus: %d\n", mCurrentStatus); + dprintf(fd, " targetStatus: %d\n", mTargetStatus); + dprintf(fd, " targetStatusTs: %lldmcs\n", (long long)(elapsedMcs(mTargetStatusTs, Clock::now()))); const auto& params = mParams; - dprintf(fd, "\t\t\tdataLoaderParams:\n"); - dprintf(fd, "\t\t\t\ttype: %s\n", toString(params.type).c_str()); - dprintf(fd, "\t\t\t\tpackageName: %s\n", params.packageName.c_str()); - dprintf(fd, "\t\t\t\tclassName: %s\n", params.className.c_str()); - dprintf(fd, "\t\t\t\targuments: %s\n", params.arguments.c_str()); + dprintf(fd, " dataLoaderParams: {\n"); + dprintf(fd, " type: %s\n", toString(params.type).c_str()); + dprintf(fd, " packageName: %s\n", params.packageName.c_str()); + dprintf(fd, " className: %s\n", params.className.c_str()); + dprintf(fd, " arguments: %s\n", params.arguments.c_str()); + dprintf(fd, " }\n"); + dprintf(fd, " }\n"); } void IncrementalService::AppOpsListener::opChanged(int32_t, const String16&) { diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h index bd01d7760a01..1de00700cad0 100644 --- a/services/incremental/IncrementalService.h +++ b/services/incremental/IncrementalService.h @@ -16,13 +16,13 @@ #pragma once -#include <android-base/strings.h> -#include <android-base/unique_fd.h> +#include <android/content/pm/BnDataLoaderStatusListener.h> #include <android/content/pm/DataLoaderParamsParcel.h> -#include <binder/IServiceManager.h> +#include <android/content/pm/IDataLoaderStatusListener.h> +#include <android/os/incremental/BnIncrementalServiceConnector.h> +#include <binder/IAppOpsCallback.h> #include <utils/String16.h> #include <utils/StrongPointer.h> -#include <utils/Vector.h> #include <ziparchive/zip_archive.h> #include <atomic> @@ -37,21 +37,14 @@ #include <string_view> #include <thread> #include <unordered_map> +#include <unordered_set> #include <utility> #include <vector> #include "ServiceWrappers.h" -#include "android/content/pm/BnDataLoaderStatusListener.h" -#include "android/os/incremental/BnIncrementalServiceConnector.h" #include "incfs.h" #include "path.h" -using namespace android::os::incremental; - -namespace android::os { -class IVold; -} - namespace android::incremental { using MountId = int; @@ -101,17 +94,14 @@ public: void onSystemReady(); - StorageId createStorage(std::string_view mountPoint, DataLoaderParamsParcel&& dataLoaderParams, + StorageId createStorage(std::string_view mountPoint, + content::pm::DataLoaderParamsParcel&& dataLoaderParams, const DataLoaderStatusListener& dataLoaderStatusListener, CreateOptions options = CreateOptions::Default); StorageId createLinkedStorage(std::string_view mountPoint, StorageId linkedStorage, CreateOptions options = CreateOptions::Default); StorageId openStorage(std::string_view path); - FileId nodeFor(StorageId storage, std::string_view path) const; - std::pair<FileId, std::string_view> parentAndNameFor(StorageId storage, - std::string_view path) const; - int bind(StorageId storage, std::string_view source, std::string_view target, BindKind kind); int unbind(StorageId storage, std::string_view target); void deleteStorage(StorageId storage); @@ -131,9 +121,9 @@ public: return false; } + RawMetadata getMetadata(StorageId storage, std::string_view path) const; RawMetadata getMetadata(StorageId storage, FileId node) const; - std::vector<std::string> listFiles(StorageId storage) const; bool startLoading(StorageId storage) const; bool configureNativeBinaries(StorageId storage, std::string_view apkFullPath, @@ -151,7 +141,7 @@ public: const std::string packageName; }; - class IncrementalServiceConnector : public BnIncrementalServiceConnector { + class IncrementalServiceConnector : public os::incremental::BnIncrementalServiceConnector { public: IncrementalServiceConnector(IncrementalService& incrementalService, int32_t storage) : incrementalService(incrementalService), storage(storage) {} @@ -163,14 +153,13 @@ public: }; private: - static const bool sEnablePerfLogging; - struct IncFsMount; - class DataLoaderStub : public android::content::pm::BnDataLoaderStatusListener { + class DataLoaderStub : public content::pm::BnDataLoaderStatusListener { public: - DataLoaderStub(IncrementalService& service, MountId id, DataLoaderParamsParcel&& params, - FileSystemControlParcel&& control, + DataLoaderStub(IncrementalService& service, MountId id, + content::pm::DataLoaderParamsParcel&& params, + content::pm::FileSystemControlParcel&& control, const DataLoaderStatusListener* externalListener); ~DataLoaderStub(); // Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will @@ -184,13 +173,14 @@ private: void onDump(int fd); MountId id() const { return mId; } - const DataLoaderParamsParcel& params() const { return mParams; } + const content::pm::DataLoaderParamsParcel& params() const { return mParams; } private: binder::Status onStatusChanged(MountId mount, int newStatus) final; bool isValid() const { return mId != kInvalidStorageId; } + bool bind(); bool create(); bool start(); bool destroy(); @@ -202,14 +192,14 @@ private: IncrementalService& mService; MountId mId = kInvalidStorageId; - DataLoaderParamsParcel mParams; - FileSystemControlParcel mControl; + content::pm::DataLoaderParamsParcel mParams; + content::pm::FileSystemControlParcel mControl; DataLoaderStatusListener mListener; std::mutex mStatusMutex; std::condition_variable mStatusCondition; - int mCurrentStatus = IDataLoaderStatusListener::DATA_LOADER_DESTROYED; - int mTargetStatus = IDataLoaderStatusListener::DATA_LOADER_DESTROYED; + int mCurrentStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED; + int mTargetStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED; TimePoint mTargetStatusTs = {}; }; using DataLoaderStubPtr = sp<DataLoaderStub>; @@ -228,7 +218,7 @@ private: using Control = incfs::UniqueControl; - using BindMap = std::map<std::string, Bind>; + using BindMap = std::map<std::string, Bind, path::PathLess>; using StorageMap = std::unordered_map<StorageId, Storage>; mutable std::mutex lock; @@ -260,7 +250,10 @@ private: using MountMap = std::unordered_map<MountId, IfsMountPtr>; using BindPathMap = std::map<std::string, IncFsMount::BindMap::iterator, path::PathLess>; - void mountExistingImages(); + static bool perfLoggingEnabled(); + + std::unordered_set<std::string_view> adoptMountedInstances(); + void mountExistingImages(const std::unordered_set<std::string_view>& mountedRootNames); bool mountExistingImage(std::string_view root); IfsMountPtr getIfs(StorageId storage) const; @@ -273,8 +266,14 @@ private: std::string&& source, std::string&& target, BindKind kind, std::unique_lock<std::mutex>& mainLock); - DataLoaderStubPtr prepareDataLoader(IncFsMount& ifs, DataLoaderParamsParcel&& params, + void addBindMountRecordLocked(IncFsMount& ifs, StorageId storage, std::string&& metadataName, + std::string&& source, std::string&& target, BindKind kind); + + DataLoaderStubPtr prepareDataLoader(IncFsMount& ifs, + content::pm::DataLoaderParamsParcel&& params, const DataLoaderStatusListener* externalListener = nullptr); + void prepareDataLoaderLocked(IncFsMount& ifs, content::pm::DataLoaderParamsParcel&& params, + const DataLoaderStatusListener* externalListener = nullptr); BindPathMap::const_iterator findStorageLocked(std::string_view path) const; StorageId findStorageId(std::string_view path) const; @@ -282,11 +281,12 @@ private: void deleteStorage(IncFsMount& ifs); void deleteStorageLocked(IncFsMount& ifs, std::unique_lock<std::mutex>&& ifsLock); MountMap::iterator getStorageSlotLocked(); - std::string normalizePathToStorage(const IfsMountPtr& incfs, StorageId storage, - std::string_view path); - std::string normalizePathToStorageLocked(IncFsMount::StorageMap::iterator storageIt, - std::string_view path); - + std::string normalizePathToStorage(const IncFsMount& incfs, StorageId storage, + std::string_view path) const; + std::string normalizePathToStorageLocked(const IncFsMount& incfs, + IncFsMount::StorageMap::const_iterator storageIt, + std::string_view path) const; + int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode); binder::Status applyStorageParams(IncFsMount& ifs, bool enableReadLogs); void registerAppOpsCallback(const std::string& packageName); diff --git a/services/incremental/IncrementalServiceValidation.cpp b/services/incremental/IncrementalServiceValidation.cpp new file mode 100644 index 000000000000..abadbbf10742 --- /dev/null +++ b/services/incremental/IncrementalServiceValidation.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "IncrementalServiceValidation.h" + +#include <android-base/stringprintf.h> +#include <binder/IPCThreadState.h> +#include <binder/PermissionCache.h> +#include <binder/PermissionController.h> +#include <errno.h> +#include <utils/String16.h> + +namespace android::incremental { + +binder::Status Ok() { + return binder::Status::ok(); +} + +binder::Status Exception(uint32_t code, const std::string& msg) { + return binder::Status::fromExceptionCode(code, String8(msg.c_str())); +} + +int fromBinderStatus(const binder::Status& status) { + return status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC + ? status.serviceSpecificErrorCode() > 0 + ? -status.serviceSpecificErrorCode() + : status.serviceSpecificErrorCode() == 0 ? -EFAULT + : status.serviceSpecificErrorCode() + : -EIO; +} + +binder::Status CheckPermissionForDataDelivery(const char* permission, const char* operation, + const char* package) { + using android::base::StringPrintf; + + int32_t pid; + int32_t uid; + + if (!PermissionCache::checkCallingPermission(String16(permission), &pid, &uid)) { + return Exception(binder::Status::EX_SECURITY, + StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission)); + } + + String16 packageName{package}; + + // Caller must also have op granted. + PermissionController pc; + if (auto packageUid = pc.getPackageUid(packageName, 0); packageUid != uid) { + return Exception(binder::Status::EX_SECURITY, + StringPrintf("UID %d / PID %d does not own package %s", uid, pid, + package)); + } + switch (auto result = pc.noteOp(String16(operation), uid, packageName); result) { + case PermissionController::MODE_ALLOWED: + case PermissionController::MODE_DEFAULT: + return binder::Status::ok(); + default: + return Exception(binder::Status::EX_SECURITY, + StringPrintf("UID %d / PID %d / package %s lacks app-op %s, error %d", + uid, pid, package, operation, result)); + } +} + +} // namespace android::incremental diff --git a/services/incremental/IncrementalServiceValidation.h b/services/incremental/IncrementalServiceValidation.h index 48894c6926c8..0e50c4db29f4 100644 --- a/services/incremental/IncrementalServiceValidation.h +++ b/services/incremental/IncrementalServiceValidation.h @@ -16,61 +16,17 @@ #pragma once -#include <android-base/stringprintf.h> -#include <binder/IPCThreadState.h> -#include <binder/PermissionCache.h> -#include <binder/PermissionController.h> #include <binder/Status.h> +#include <stdint.h> -namespace android::incremental { - -inline binder::Status Ok() { - return binder::Status::ok(); -} - -inline binder::Status Exception(uint32_t code, const std::string& msg) { - return binder::Status::fromExceptionCode(code, String8(msg.c_str())); -} - -inline int fromBinderStatus(const binder::Status& status) { - return status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC - ? status.serviceSpecificErrorCode() > 0 ? -status.serviceSpecificErrorCode() - : status.serviceSpecificErrorCode() == 0 - ? -EFAULT - : status.serviceSpecificErrorCode() - : -EIO; -} +#include <string> -inline binder::Status CheckPermissionForDataDelivery(const char* permission, const char* operation, - const char* package) { - using android::base::StringPrintf; - - int32_t pid; - int32_t uid; - - if (!PermissionCache::checkCallingPermission(String16(permission), &pid, &uid)) { - return Exception(binder::Status::EX_SECURITY, - StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission)); - } - - String16 packageName{package}; +namespace android::incremental { - // Caller must also have op granted. - PermissionController pc; - if (auto packageUid = pc.getPackageUid(packageName, 0); packageUid != uid) { - return Exception(binder::Status::EX_SECURITY, - StringPrintf("UID %d / PID %d does not own package %s", uid, pid, - package)); - } - switch (auto result = pc.noteOp(String16(operation), uid, packageName); result) { - case PermissionController::MODE_ALLOWED: - case PermissionController::MODE_DEFAULT: - return binder::Status::ok(); - default: - return Exception(binder::Status::EX_SECURITY, - StringPrintf("UID %d / PID %d / package %s lacks app-op %s, error %d", - uid, pid, package, operation, result)); - } -} +binder::Status Ok(); +binder::Status Exception(uint32_t code, const std::string& msg); +int fromBinderStatus(const binder::Status& status); +binder::Status CheckPermissionForDataDelivery(const char* permission, const char* operation, + const char* package); } // namespace android::incremental diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp index bf8e696a264c..85f744152ea4 100644 --- a/services/incremental/ServiceWrappers.cpp +++ b/services/incremental/ServiceWrappers.cpp @@ -18,23 +18,29 @@ #include "ServiceWrappers.h" +#include <MountRegistry.h> #include <android-base/logging.h> +#include <android/content/pm/IDataLoaderManager.h> +#include <android/os/IVold.h> +#include <binder/AppOpsManager.h> #include <utils/String16.h> +#include "IncrementalServiceValidation.h" + using namespace std::literals; -namespace android::os::incremental { +namespace android::incremental { static constexpr auto kVoldServiceName = "vold"sv; static constexpr auto kDataLoaderManagerName = "dataloader_manager"sv; class RealVoldService : public VoldServiceWrapper { public: - RealVoldService(const sp<os::IVold> vold) : mInterface(std::move(vold)) {} + RealVoldService(sp<os::IVold> vold) : mInterface(std::move(vold)) {} ~RealVoldService() = default; - binder::Status mountIncFs(const std::string& backingPath, const std::string& targetDir, - int32_t flags, - IncrementalFileSystemControlParcel* _aidl_return) const final { + binder::Status mountIncFs( + const std::string& backingPath, const std::string& targetDir, int32_t flags, + os::incremental::IncrementalFileSystemControlParcel* _aidl_return) const final { return mInterface->mountIncFs(backingPath, targetDir, flags, _aidl_return); } binder::Status unmountIncFs(const std::string& dir) const final { @@ -56,20 +62,21 @@ private: class RealDataLoaderManager : public DataLoaderManagerWrapper { public: - RealDataLoaderManager(const sp<content::pm::IDataLoaderManager> manager) - : mInterface(manager) {} + RealDataLoaderManager(sp<content::pm::IDataLoaderManager> manager) + : mInterface(std::move(manager)) {} ~RealDataLoaderManager() = default; - binder::Status initializeDataLoader(MountId mountId, const DataLoaderParamsParcel& params, - const FileSystemControlParcel& control, - const sp<IDataLoaderStatusListener>& listener, - bool* _aidl_return) const final { - return mInterface->initializeDataLoader(mountId, params, control, listener, _aidl_return); + binder::Status bindToDataLoader(MountId mountId, + const content::pm::DataLoaderParamsParcel& params, + const sp<content::pm::IDataLoaderStatusListener>& listener, + bool* _aidl_return) const final { + return mInterface->bindToDataLoader(mountId, params, listener, _aidl_return); } - binder::Status getDataLoader(MountId mountId, sp<IDataLoader>* _aidl_return) const final { + binder::Status getDataLoader(MountId mountId, + sp<content::pm::IDataLoader>* _aidl_return) const final { return mInterface->getDataLoader(mountId, _aidl_return); } - binder::Status destroyDataLoader(MountId mountId) const final { - return mInterface->destroyDataLoader(mountId); + binder::Status unbindFromDataLoader(MountId mountId) const final { + return mInterface->unbindFromDataLoader(mountId); } private: @@ -109,21 +116,31 @@ private: class RealIncFs : public IncFsWrapper { public: RealIncFs() = default; - ~RealIncFs() = default; + ~RealIncFs() final = default; + void listExistingMounts(const ExistingMountCallback& cb) const final { + for (auto mount : incfs::defaultMountRegistry().copyMounts()) { + auto binds = mount.binds(); // span() doesn't like rvalue containers, needs to save it. + cb(mount.root(), mount.backingDir(), binds); + } + } + Control openMount(std::string_view path) const final { return incfs::open(path); } Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const final { return incfs::createControl(cmd, pendingReads, logs); } ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id, - NewFileParams params) const final { + incfs::NewFileParams params) const final { return incfs::makeFile(control, path, mode, id, params); } ErrorCode makeDir(const Control& control, std::string_view path, int mode) const final { return incfs::makeDir(control, path, mode); } - RawMetadata getMetadata(const Control& control, FileId fileid) const final { + ErrorCode makeDirs(const Control& control, std::string_view path, int mode) const final { + return incfs::makeDirs(control, path, mode); + } + incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const final { return incfs::getMetadata(control, fileid); } - RawMetadata getMetadata(const Control& control, std::string_view path) const final { + incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const final { return incfs::getMetadata(control, path); } FileId getFileId(const Control& control, std::string_view path) const final { @@ -138,8 +155,8 @@ public: base::unique_fd openForSpecialOps(const Control& control, FileId id) const final { return base::unique_fd{incfs::openForSpecialOps(control, id).release()}; } - ErrorCode writeBlocks(Span<const DataBlock> blocks) const final { - return incfs::writeBlocks(blocks); + ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const final { + return incfs::writeBlocks({blocks.data(), size_t(blocks.size())}); } }; @@ -165,8 +182,9 @@ std::unique_ptr<VoldServiceWrapper> RealServiceManager::getVoldService() { } std::unique_ptr<DataLoaderManagerWrapper> RealServiceManager::getDataLoaderManager() { - sp<IDataLoaderManager> manager = - RealServiceManager::getRealService<IDataLoaderManager>(kDataLoaderManagerName); + sp<content::pm::IDataLoaderManager> manager = + RealServiceManager::getRealService<content::pm::IDataLoaderManager>( + kDataLoaderManagerName); if (manager) { return std::make_unique<RealDataLoaderManager>(manager); } @@ -239,4 +257,4 @@ JavaVM* RealJniWrapper::getJvm(JNIEnv* env) { return getJavaVm(env); } -} // namespace android::os::incremental +} // namespace android::incremental diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h index 142bf2ef32f3..37928308b506 100644 --- a/services/incremental/ServiceWrappers.h +++ b/services/incremental/ServiceWrappers.h @@ -16,29 +16,23 @@ #pragma once -#include "IncrementalServiceValidation.h" - -#include <android-base/strings.h> #include <android-base/unique_fd.h> #include <android/content/pm/DataLoaderParamsParcel.h> #include <android/content/pm/FileSystemControlParcel.h> #include <android/content/pm/IDataLoader.h> -#include <android/content/pm/IDataLoaderManager.h> #include <android/content/pm/IDataLoaderStatusListener.h> -#include <android/os/IVold.h> -#include <binder/AppOpsManager.h> +#include <binder/IAppOpsCallback.h> #include <binder/IServiceManager.h> +#include <binder/Status.h> #include <incfs.h> #include <jni.h> #include <memory> +#include <span> #include <string> #include <string_view> -using namespace android::incfs; -using namespace android::content::pm; - -namespace android::os::incremental { +namespace android::incremental { // --- Wrapper interfaces --- @@ -47,42 +41,54 @@ using MountId = int32_t; class VoldServiceWrapper { public: virtual ~VoldServiceWrapper() = default; - virtual binder::Status mountIncFs(const std::string& backingPath, const std::string& targetDir, - int32_t flags, - IncrementalFileSystemControlParcel* _aidl_return) const = 0; + virtual binder::Status mountIncFs( + const std::string& backingPath, const std::string& targetDir, int32_t flags, + os::incremental::IncrementalFileSystemControlParcel* result) const = 0; virtual binder::Status unmountIncFs(const std::string& dir) const = 0; virtual binder::Status bindMount(const std::string& sourceDir, const std::string& targetDir) const = 0; - virtual binder::Status setIncFsMountOptions(const ::android::os::incremental::IncrementalFileSystemControlParcel& control, bool enableReadLogs) const = 0; + virtual binder::Status setIncFsMountOptions( + const os::incremental::IncrementalFileSystemControlParcel& control, + bool enableReadLogs) const = 0; }; class DataLoaderManagerWrapper { public: virtual ~DataLoaderManagerWrapper() = default; - virtual binder::Status initializeDataLoader(MountId mountId, - const DataLoaderParamsParcel& params, - const FileSystemControlParcel& control, - const sp<IDataLoaderStatusListener>& listener, - bool* _aidl_return) const = 0; - virtual binder::Status getDataLoader(MountId mountId, sp<IDataLoader>* _aidl_return) const = 0; - virtual binder::Status destroyDataLoader(MountId mountId) const = 0; + virtual binder::Status bindToDataLoader( + MountId mountId, const content::pm::DataLoaderParamsParcel& params, + const sp<content::pm::IDataLoaderStatusListener>& listener, bool* result) const = 0; + virtual binder::Status getDataLoader(MountId mountId, + sp<content::pm::IDataLoader>* result) const = 0; + virtual binder::Status unbindFromDataLoader(MountId mountId) const = 0; }; class IncFsWrapper { public: + using Control = incfs::Control; + using FileId = incfs::FileId; + using ErrorCode = incfs::ErrorCode; + + using ExistingMountCallback = + std::function<void(std::string_view root, std::string_view backingDir, + std::span<std::pair<std::string_view, std::string_view>> binds)>; + virtual ~IncFsWrapper() = default; + virtual void listExistingMounts(const ExistingMountCallback& cb) const = 0; + virtual Control openMount(std::string_view path) const = 0; virtual Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const = 0; virtual ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id, - NewFileParams params) const = 0; + incfs::NewFileParams params) const = 0; virtual ErrorCode makeDir(const Control& control, std::string_view path, int mode) const = 0; - virtual RawMetadata getMetadata(const Control& control, FileId fileid) const = 0; - virtual RawMetadata getMetadata(const Control& control, std::string_view path) const = 0; + virtual ErrorCode makeDirs(const Control& control, std::string_view path, int mode) const = 0; + virtual incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const = 0; + virtual incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const = 0; virtual FileId getFileId(const Control& control, std::string_view path) const = 0; virtual ErrorCode link(const Control& control, std::string_view from, std::string_view to) const = 0; virtual ErrorCode unlink(const Control& control, std::string_view path) const = 0; virtual base::unique_fd openForSpecialOps(const Control& control, FileId id) const = 0; - virtual ErrorCode writeBlocks(Span<const DataBlock> blocks) const = 0; + virtual ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const = 0; }; class AppOpsManagerWrapper { @@ -129,4 +135,4 @@ private: JavaVM* const mJvm; }; -} // namespace android::os::incremental +} // namespace android::incremental diff --git a/services/incremental/path.cpp b/services/incremental/path.cpp index 0d86f2a984d6..338659d40b46 100644 --- a/services/incremental/path.cpp +++ b/services/incremental/path.cpp @@ -44,7 +44,7 @@ bool PathLess::operator()(std::string_view l, std::string_view r) const { PathCharsLess()); } -static void preparePathComponent(std::string_view path, bool trimFront) { +static void preparePathComponent(std::string_view& path, bool trimFront) { if (trimFront) { while (!path.empty() && path.front() == '/') { path.remove_prefix(1); diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp index bfe92f4f2080..2205bfed15d1 100644 --- a/services/incremental/test/IncrementalServiceTest.cpp +++ b/services/incremental/test/IncrementalServiceTest.cpp @@ -25,6 +25,7 @@ #include <future> #include "IncrementalService.h" +#include "IncrementalServiceValidation.h" #include "Metadata.pb.h" #include "ServiceWrappers.h" @@ -130,18 +131,19 @@ public: .WillByDefault(Invoke(this, &MockDataLoader::createOkNoStatus)); } - binder::Status createOk(int32_t id, const content::pm::DataLoaderParamsParcel&, - const content::pm::FileSystemControlParcel&, + binder::Status createOk(int32_t id, const content::pm::DataLoaderParamsParcel& params, + const content::pm::FileSystemControlParcel& control, const sp<content::pm::IDataLoaderStatusListener>& listener) { - mListener = listener; + createOkNoStatus(id, params, control, listener); if (mListener) { mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_CREATED); } return binder::Status::ok(); } - binder::Status createOkNoStatus(int32_t id, const content::pm::DataLoaderParamsParcel&, - const content::pm::FileSystemControlParcel&, + binder::Status createOkNoStatus(int32_t id, const content::pm::DataLoaderParamsParcel& params, + const content::pm::FileSystemControlParcel& control, const sp<content::pm::IDataLoaderStatusListener>& listener) { + mServiceConnector = control.service; mListener = listener; return binder::Status::ok(); } @@ -172,8 +174,15 @@ public: } return binder::Status::ok(); } + int32_t setStorageParams(bool enableReadLogs) { + int32_t result = -1; + EXPECT_NE(mServiceConnector.get(), nullptr); + EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk()); + return result; + } private: + sp<IIncrementalServiceConnector> mServiceConnector; sp<IDataLoaderStatusListener> mListener; }; @@ -183,21 +192,20 @@ public: EXPECT_TRUE(mDataLoaderHolder != nullptr); } - MOCK_CONST_METHOD5(initializeDataLoader, + MOCK_CONST_METHOD4(bindToDataLoader, binder::Status(int32_t mountId, const DataLoaderParamsParcel& params, - const FileSystemControlParcel& control, const sp<IDataLoaderStatusListener>& listener, bool* _aidl_return)); MOCK_CONST_METHOD2(getDataLoader, binder::Status(int32_t mountId, sp<IDataLoader>* _aidl_return)); - MOCK_CONST_METHOD1(destroyDataLoader, binder::Status(int32_t mountId)); + MOCK_CONST_METHOD1(unbindFromDataLoader, binder::Status(int32_t mountId)); - void initializeDataLoaderSuccess() { - ON_CALL(*this, initializeDataLoader(_, _, _, _, _)) - .WillByDefault(Invoke(this, &MockDataLoaderManager::initializeDataLoaderOk)); + void bindToDataLoaderSuccess() { + ON_CALL(*this, bindToDataLoader(_, _, _, _)) + .WillByDefault(Invoke(this, &MockDataLoaderManager::bindToDataLoaderOk)); } - void initializeDataLoaderFails() { - ON_CALL(*this, initializeDataLoader(_, _, _, _, _)) + void bindToDataLoaderFails() { + ON_CALL(*this, bindToDataLoader(_, _, _, _)) .WillByDefault(Return( (binder::Status::fromExceptionCode(1, String8("failed to prepare"))))); } @@ -205,20 +213,21 @@ public: ON_CALL(*this, getDataLoader(_, _)) .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk)); } - void destroyDataLoaderSuccess() { - ON_CALL(*this, destroyDataLoader(_)) - .WillByDefault(Invoke(this, &MockDataLoaderManager::destroyDataLoaderOk)); + void unbindFromDataLoaderSuccess() { + ON_CALL(*this, unbindFromDataLoader(_)) + .WillByDefault(Invoke(this, &MockDataLoaderManager::unbindFromDataLoaderOk)); } - binder::Status initializeDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params, - const FileSystemControlParcel& control, - const sp<IDataLoaderStatusListener>& listener, - bool* _aidl_return) { + binder::Status bindToDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params, + const sp<IDataLoaderStatusListener>& listener, + bool* _aidl_return) { mId = mountId; mListener = listener; - mServiceConnector = control.service; mDataLoader = mDataLoaderHolder; *_aidl_return = true; - return mDataLoader->create(mountId, params, control, listener); + if (mListener) { + mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BOUND); + } + return binder::Status::ok(); } binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) { *_aidl_return = mDataLoader; @@ -233,7 +242,7 @@ public: void setDataLoaderStatusDestroyed() { mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED); } - binder::Status destroyDataLoaderOk(int32_t id) { + binder::Status unbindFromDataLoaderOk(int32_t id) { if (mDataLoader) { if (auto status = mDataLoader->destroy(id); !status.isOk()) { return status; @@ -245,28 +254,25 @@ public: } return binder::Status::ok(); } - int32_t setStorageParams(bool enableReadLogs) { - int32_t result = -1; - EXPECT_NE(mServiceConnector.get(), nullptr); - EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk()); - return result; - } private: int mId; sp<IDataLoaderStatusListener> mListener; - sp<IIncrementalServiceConnector> mServiceConnector; sp<IDataLoader> mDataLoader; sp<IDataLoader> mDataLoaderHolder; }; class MockIncFs : public IncFsWrapper { public: + MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb)); + MOCK_CONST_METHOD1(openMount, Control(std::string_view path)); MOCK_CONST_METHOD3(createControl, Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs)); MOCK_CONST_METHOD5(makeFile, ErrorCode(const Control& control, std::string_view path, int mode, FileId id, NewFileParams params)); MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode)); + MOCK_CONST_METHOD3(makeDirs, + ErrorCode(const Control& control, std::string_view path, int mode)); MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid)); MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path)); MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path)); @@ -274,10 +280,13 @@ public: ErrorCode(const Control& control, std::string_view from, std::string_view to)); MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path)); MOCK_CONST_METHOD2(openForSpecialOps, base::unique_fd(const Control& control, FileId id)); - MOCK_CONST_METHOD1(writeBlocks, ErrorCode(Span<const DataBlock> blocks)); + MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks)); + + MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); } void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); } void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); } + RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) { metadata::Mount m; m.mutable_storage()->set_id(100); @@ -395,7 +404,7 @@ public: mRootDir.path); mDataLoaderParcel.packageName = "com.test"; mDataLoaderParcel.arguments = "uri"; - mDataLoaderManager->destroyDataLoaderSuccess(); + mDataLoaderManager->unbindFromDataLoaderSuccess(); mIncrementalService->onSystemReady(); } @@ -434,7 +443,7 @@ protected: TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) { mVold->mountIncFsFails(); - EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0); + EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0); TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, @@ -444,8 +453,8 @@ TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) { TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) { mVold->mountIncFsInvalidControlParcel(); - EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(0); + EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0); TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, @@ -456,8 +465,8 @@ TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) { mVold->mountIncFsSuccess(); mIncFs->makeFileFails(); - EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(0); + EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0); EXPECT_CALL(*mVold, unmountIncFs(_)); TemporaryDir tempDir; int storageId = @@ -470,8 +479,8 @@ TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) { mVold->mountIncFsSuccess(); mIncFs->makeFileSuccess(); mVold->bindMountFails(); - EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(0); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(0); + EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0); EXPECT_CALL(*mVold, unmountIncFs(_)); TemporaryDir tempDir; int storageId = @@ -484,9 +493,9 @@ TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) { mVold->mountIncFsSuccess(); mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); - mDataLoaderManager->initializeDataLoaderFails(); - EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(1); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(0); + mDataLoaderManager->bindToDataLoaderFails(); + EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0); EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0); EXPECT_CALL(*mDataLoader, start(_)).Times(0); EXPECT_CALL(*mDataLoader, destroy(_)).Times(0); @@ -502,9 +511,10 @@ TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) { mVold->mountIncFsSuccess(); mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); - mDataLoaderManager->initializeDataLoaderSuccess(); - EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(1); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(1); + mDataLoaderManager->bindToDataLoaderSuccess(); + mDataLoaderManager->getDataLoaderSuccess(); + EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1); EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1); EXPECT_CALL(*mDataLoader, start(_)).Times(0); EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); @@ -521,10 +531,10 @@ TEST_F(IncrementalServiceTest, testDataLoaderDestroyed) { mVold->mountIncFsSuccess(); mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); - mDataLoaderManager->initializeDataLoaderSuccess(); + mDataLoaderManager->bindToDataLoaderSuccess(); mDataLoaderManager->getDataLoaderSuccess(); - EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(2); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(1); + EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1); EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2); EXPECT_CALL(*mDataLoader, start(_)).Times(0); EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); @@ -543,10 +553,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) { mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); mDataLoader->initializeCreateOkNoStatus(); - mDataLoaderManager->initializeDataLoaderSuccess(); + mDataLoaderManager->bindToDataLoaderSuccess(); mDataLoaderManager->getDataLoaderSuccess(); - EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(1); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(1); + EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1); EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1); EXPECT_CALL(*mDataLoader, start(_)).Times(1); EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); @@ -566,10 +576,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) { mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); mDataLoader->initializeCreateOkNoStatus(); - mDataLoaderManager->initializeDataLoaderSuccess(); + mDataLoaderManager->bindToDataLoaderSuccess(); mDataLoaderManager->getDataLoaderSuccess(); - EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(2); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(1); + EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1); EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2); EXPECT_CALL(*mDataLoader, start(_)).Times(1); EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); @@ -588,10 +598,10 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) { mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); mVold->setIncFsMountOptionsSuccess(); - mDataLoaderManager->initializeDataLoaderSuccess(); + mDataLoaderManager->bindToDataLoaderSuccess(); mDataLoaderManager->getDataLoaderSuccess(); mAppOpsManager->checkPermissionSuccess(); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); // We are calling setIncFsMountOptions(true). EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1); @@ -604,7 +614,7 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) { mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); - ASSERT_GE(mDataLoaderManager->setStorageParams(true), 0); + ASSERT_GE(mDataLoader->setStorageParams(true), 0); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) { @@ -612,11 +622,11 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChang mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); mVold->setIncFsMountOptionsSuccess(); - mDataLoaderManager->initializeDataLoaderSuccess(); + mDataLoaderManager->bindToDataLoaderSuccess(); mDataLoaderManager->getDataLoaderSuccess(); mAppOpsManager->checkPermissionSuccess(); mAppOpsManager->initializeStartWatchingMode(); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); // We are calling setIncFsMountOptions(true). EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1); @@ -631,7 +641,7 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChang mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); - ASSERT_GE(mDataLoaderManager->setStorageParams(true), 0); + ASSERT_GE(mDataLoader->setStorageParams(true), 0); ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get()); mAppOpsManager->mStoredCallback->opChanged(0, {}); } @@ -640,10 +650,10 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) { mVold->mountIncFsSuccess(); mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); - mDataLoaderManager->initializeDataLoaderSuccess(); + mDataLoaderManager->bindToDataLoaderSuccess(); mDataLoaderManager->getDataLoaderSuccess(); mAppOpsManager->checkPermissionFails(); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); // checkPermission fails, no calls to set opitions, start or stop WatchingMode. EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0); @@ -654,7 +664,7 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) { mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); - ASSERT_LT(mDataLoaderManager->setStorageParams(true), 0); + ASSERT_LT(mDataLoader->setStorageParams(true), 0); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) { @@ -662,10 +672,10 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) { mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); mVold->setIncFsMountOptionsFails(); - mDataLoaderManager->initializeDataLoaderSuccess(); + mDataLoaderManager->bindToDataLoaderSuccess(); mDataLoaderManager->getDataLoaderSuccess(); mAppOpsManager->checkPermissionSuccess(); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)); + EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); // We are calling setIncFsMountOptions. EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1); @@ -677,14 +687,14 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) { mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); - ASSERT_LT(mDataLoaderManager->setStorageParams(true), 0); + ASSERT_LT(mDataLoader->setStorageParams(true), 0); } TEST_F(IncrementalServiceTest, testMakeDirectory) { mVold->mountIncFsSuccess(); mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); - mDataLoaderManager->initializeDataLoaderSuccess(); + mDataLoaderManager->bindToDataLoaderSuccess(); mDataLoaderManager->getDataLoaderSuccess(); TemporaryDir tempDir; int storageId = @@ -692,14 +702,14 @@ TEST_F(IncrementalServiceTest, testMakeDirectory) { IncrementalService::CreateOptions::CreateNew); std::string dir_path("test"); - std::string tempPath(tempDir.path); - std::replace(tempPath.begin(), tempPath.end(), '/', '_'); - std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1); - std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path; - // Expecting incfs to call makeDir on a path like: - // /data/local/tmp/TemporaryDir-06yixG/data_local_tmp_TemporaryDir-xwdFhT/mount/st_1_0/test - EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _)); + // <root>/*/mount/<storage>/test + EXPECT_CALL(*mIncFs, + makeDir(_, Truly([&](std::string_view arg) { + return arg.starts_with(mRootDir.path) && + arg.ends_with("/mount/st_1_0/" + dir_path); + }), + _)); auto res = mIncrementalService->makeDir(storageId, dir_path, 0555); ASSERT_EQ(res, 0); } @@ -708,7 +718,7 @@ TEST_F(IncrementalServiceTest, testMakeDirectories) { mVold->mountIncFsSuccess(); mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); - mDataLoaderManager->initializeDataLoaderSuccess(); + mDataLoaderManager->bindToDataLoaderSuccess(); mDataLoaderManager->getDataLoaderSuccess(); TemporaryDir tempDir; int storageId = @@ -717,29 +727,15 @@ TEST_F(IncrementalServiceTest, testMakeDirectories) { auto first = "first"sv; auto second = "second"sv; auto third = "third"sv; - - std::string tempPath(tempDir.path); - std::replace(tempPath.begin(), tempPath.end(), '/', '_'); - std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1); - - InSequence seq; - auto parent_path = std::string(first) + "/" + std::string(second); - auto dir_path = parent_path + "/" + std::string(third); - - std::string normalized_first_path = mount_dir + "/mount/st_1_0/" + std::string(first); - std::string normalized_parent_path = mount_dir + "/mount/st_1_0/" + parent_path; - std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path; - - EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _)) - .WillOnce(Return(-ENOENT)); - EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _)) - .WillOnce(Return(-ENOENT)); - EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_first_path), _)) - .WillOnce(Return(0)); - EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _)) - .WillOnce(Return(0)); - EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _)).WillOnce(Return(0)); - auto res = mIncrementalService->makeDirs(storageId, normalized_dir_path, 0555); + auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third); + + EXPECT_CALL(*mIncFs, + makeDirs(_, Truly([&](std::string_view arg) { + return arg.starts_with(mRootDir.path) && + arg.ends_with("/mount/st_1_0/" + dir_path); + }), + _)); + auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555); ASSERT_EQ(res, 0); } } // namespace android::os::incremental diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 289d79dad367..0fc333f4b38c 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -2174,12 +2174,6 @@ public final class SystemServer { mPackageManagerService.systemReady(); t.traceEnd(); - if (mIncrementalServiceHandle != 0) { - t.traceBegin("MakeIncrementalServiceReady"); - setIncrementalServiceSystemReady(mIncrementalServiceHandle); - t.traceEnd(); - } - t.traceBegin("MakeDisplayManagerServiceReady"); try { // TODO: use boot phase and communicate these flags some other way @@ -2449,6 +2443,12 @@ public final class SystemServer { reportWtf("Notifying incident daemon running", e); } t.traceEnd(); + + if (mIncrementalServiceHandle != 0) { + t.traceBegin("MakeIncrementalServiceReady"); + setIncrementalServiceSystemReady(mIncrementalServiceHandle); + t.traceEnd(); + } }, t); t.traceEnd(); // startOtherServices diff --git a/services/net/Android.bp b/services/net/Android.bp index 9f2979906d42..bb5409b3e032 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -41,6 +41,7 @@ java_library { sdk_version: "module_current", libs: [ "unsupportedappusage", + "framework-wifi-util-lib", ], static_libs: [ "dnsresolver_aidl_interface-V2-java", diff --git a/services/people/java/com/android/server/people/data/ConversationInfo.java b/services/people/java/com/android/server/people/data/ConversationInfo.java index dc3fa2a048f6..27fa36b70b8f 100644 --- a/services/people/java/com/android/server/people/data/ConversationInfo.java +++ b/services/people/java/com/android/server/people/data/ConversationInfo.java @@ -62,6 +62,8 @@ public class ConversationInfo { private static final int FLAG_DEMOTED = 1 << 6; + private static final int FLAG_NOTIFICATION_SETTING_CHANGED = 1 << 7; + @IntDef(flag = true, prefix = {"FLAG_"}, value = { FLAG_IMPORTANT, FLAG_NOTIFICATION_SILENCED, @@ -70,6 +72,7 @@ public class ConversationInfo { FLAG_PERSON_BOT, FLAG_CONTACT_STARRED, FLAG_DEMOTED, + FLAG_NOTIFICATION_SETTING_CHANGED, }) @Retention(RetentionPolicy.SOURCE) private @interface ConversationFlags { @@ -185,6 +188,11 @@ public class ConversationInfo { return hasConversationFlags(FLAG_CONTACT_STARRED); } + /** Whether the conversation's notification setting has ever been changed by the user. */ + boolean isNotificationSettingChanged() { + return hasConversationFlags(FLAG_NOTIFICATION_SETTING_CHANGED); + } + @Override public boolean equals(Object obj) { if (this == obj) { @@ -491,6 +499,10 @@ public class ConversationInfo { return setConversationFlag(FLAG_CONTACT_STARRED, value); } + Builder setNotificationSettingChanged(boolean value) { + return setConversationFlag(FLAG_NOTIFICATION_SETTING_CHANGED, value); + } + private Builder setConversationFlag(@ConversationFlags int flags, boolean value) { if (value) { return addConversationFlags(flags); 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 763e19bd14ab..8e1141da9df1 100644 --- a/services/people/java/com/android/server/people/data/DataManager.java +++ b/services/people/java/com/android/server/people/data/DataManager.java @@ -16,6 +16,8 @@ package com.android.server.people.data; +import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE; + import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; @@ -56,6 +58,7 @@ import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.telecom.TelecomManager; import android.text.format.DateUtils; +import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; @@ -482,7 +485,8 @@ public class DataManager { } @Nullable - private EventHistoryImpl getEventHistoryIfEligible(StatusBarNotification sbn) { + private PackageData getPackageIfConversationExists(StatusBarNotification sbn, + Consumer<ConversationInfo> conversationConsumer) { Notification notification = sbn.getNotification(); String shortcutId = notification.getShortcutId(); if (shortcutId == null) { @@ -490,12 +494,16 @@ public class DataManager { } PackageData packageData = getPackage(sbn.getPackageName(), sbn.getUser().getIdentifier()); - if (packageData == null - || packageData.getConversationStore().getConversation(shortcutId) == null) { + if (packageData == null) { + return null; + } + ConversationInfo conversationInfo = + packageData.getConversationStore().getConversation(shortcutId); + if (conversationInfo == null) { return null; } - return packageData.getEventStore().getOrCreateEventHistory( - EventStore.CATEGORY_SHORTCUT_BASED, shortcutId); + conversationConsumer.accept(conversationInfo); + return packageData; } @VisibleForTesting @@ -745,10 +753,19 @@ public class DataManager { /** Listener for the notifications and their settings changes. */ private class NotificationListener extends NotificationListenerService { + // Conversation shortcut ID -> Number of active notifications + private final Map<String, Integer> mActiveNotifCounts = new ArrayMap<>(); + @Override public void onNotificationPosted(StatusBarNotification sbn) { - EventHistoryImpl eventHistory = getEventHistoryIfEligible(sbn); - if (eventHistory != null) { + String shortcutId = sbn.getNotification().getShortcutId(); + PackageData packageData = getPackageIfConversationExists(sbn, conversationInfo -> { + mActiveNotifCounts.merge(shortcutId, 1, Integer::sum); + }); + + if (packageData != null) { + EventHistoryImpl eventHistory = packageData.getEventStore().getOrCreateEventHistory( + EventStore.CATEGORY_SHORTCUT_BASED, shortcutId); eventHistory.addEvent(new Event(sbn.getPostTime(), Event.TYPE_NOTIFICATION_POSTED)); } } @@ -756,13 +773,32 @@ public class DataManager { @Override public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap, int reason) { - if (reason != REASON_CLICK) { - return; - } - EventHistoryImpl eventHistory = getEventHistoryIfEligible(sbn); - if (eventHistory == null) { + String shortcutId = sbn.getNotification().getShortcutId(); + PackageData packageData = getPackageIfConversationExists(sbn, conversationInfo -> { + int count = mActiveNotifCounts.getOrDefault(shortcutId, 0) - 1; + if (count <= 0) { + mActiveNotifCounts.remove(sbn.getNotification().getShortcutId()); + // The shortcut was cached by Notification Manager synchronously when the + // associated notification was posted. Uncache it here when all the associated + // notifications are removed. + if (conversationInfo.isShortcutCached() + && !conversationInfo.isNotificationSettingChanged()) { + int userId = sbn.getUser().getIdentifier(); + mShortcutServiceInternal.uncacheShortcuts(userId, + mContext.getPackageName(), sbn.getPackageName(), + Collections.singletonList(conversationInfo.getShortcutId()), + userId); + } + } else { + mActiveNotifCounts.put(shortcutId, count); + } + }); + + if (reason != REASON_CLICK || packageData == null) { return; } + EventHistoryImpl eventHistory = packageData.getEventStore().getOrCreateEventHistory( + EventStore.CATEGORY_SHORTCUT_BASED, shortcutId); long currentTime = System.currentTimeMillis(); eventHistory.addEvent(new Event(currentTime, Event.TYPE_NOTIFICATION_OPENED)); } @@ -780,7 +816,16 @@ public class DataManager { if (conversationInfo == null) { return; } + boolean isNotificationSettingChanged = + conversationInfo.isImportant() != channel.isImportantConversation() + || conversationInfo.isDemoted() != channel.isDemoted() + || channel.hasUserSetImportance() + || (channel.getUserLockedFields() & USER_LOCKED_ALLOW_BUBBLE) != 0; ConversationInfo.Builder builder = new ConversationInfo.Builder(conversationInfo); + if (modificationType == NOTIFICATION_CHANNEL_OR_GROUP_UPDATED + && isNotificationSettingChanged) { + builder.setNotificationSettingChanged(true); + } switch (modificationType) { case NOTIFICATION_CHANNEL_OR_GROUP_ADDED: case NOTIFICATION_CHANNEL_OR_GROUP_UPDATED: @@ -802,15 +847,6 @@ public class DataManager { break; } conversationStore.addOrUpdate(builder.build()); - - if (modificationType == NOTIFICATION_CHANNEL_OR_GROUP_UPDATED - && conversationInfo.isShortcutLongLived() - && !conversationInfo.isShortcutCached()) { - mShortcutServiceInternal.cacheShortcuts(user.getIdentifier(), - mContext.getPackageName(), pkg, - Collections.singletonList(conversationInfo.getShortcutId()), - user.getIdentifier()); - } } } 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 7a175ca1b7f5..2983d585c45a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -541,7 +541,7 @@ public class MockingOomAdjusterTests { doReturn(new ArrayMap<IBinder, ArrayList<ConnectionRecord>>()).when(s).getConnections(); s.startRequested = true; s.lastActivity = SystemClock.uptimeMillis(); - app.services.add(s); + app.startService(s); sService.mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; sService.mOomAdjuster.updateOomAdjLocked(app, false, OomAdjuster.OOM_ADJ_REASON_NONE); @@ -585,7 +585,7 @@ public class MockingOomAdjusterTests { doReturn(new ArrayMap<IBinder, ArrayList<ConnectionRecord>>()).when(s).getConnections(); s.startRequested = true; s.lastActivity = SystemClock.uptimeMillis(); - app.services.add(s); + app.startService(s); sService.mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; sService.mOomAdjuster.updateOomAdjLocked(app, false, OomAdjuster.OOM_ADJ_REASON_NONE); @@ -1593,7 +1593,7 @@ public class MockingOomAdjusterTests { s.app = app3; setFieldValue(ServiceRecord.class, s, "connections", new ArrayMap<IBinder, ArrayList<ConnectionRecord>>()); - app3.services.add(s); + app3.startService(s); doCallRealMethod().when(s).getConnections(); s.startRequested = true; s.lastActivity = now; @@ -1698,7 +1698,7 @@ public class MockingOomAdjusterTests { record.app = service; setFieldValue(ServiceRecord.class, record, "connections", new ArrayMap<IBinder, ArrayList<ConnectionRecord>>()); - service.services.add(record); + service.startService(record); doCallRealMethod().when(record).getConnections(); } AppBindRecord binding = new AppBindRecord(record, null, client); diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java index 3e5c21c67bb3..cbe49eb12f95 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java @@ -124,6 +124,9 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi // Key is a pair of uri and userId private final Map<Pair<Uri, Integer>, ContentObserver> mContentObservers = new ArrayMap<>(); + // Used as an override when set to nonzero. + private long mCurrentTimeMillis = 0; + public MockInjector(MockSystemServices services, DpmMockContext context) { super(context); this.services = services; @@ -470,5 +473,19 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi @Override public void runCryptoSelfTest() {} + + @Override + public String[] getPersonalAppsForSuspension(int userId) { + return new String[]{}; + } + + public void setSystemCurrentTimeMillis(long value) { + mCurrentTimeMillis = value; + } + + @Override + public long systemCurrentTimeMillis() { + return mCurrentTimeMillis != 0 ? mCurrentTimeMillis : System.currentTimeMillis(); + } } } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 57039e53429e..b042e7794666 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -44,6 +44,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isNull; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atMost; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; @@ -62,6 +63,7 @@ import android.Manifest.permission; import android.app.Activity; import android.app.AppOpsManager; import android.app.Notification; +import android.app.PendingIntent; import android.app.admin.DeviceAdminReceiver; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; @@ -96,6 +98,7 @@ import android.util.Pair; import androidx.test.filters.SmallTest; import com.android.internal.R; +import com.android.internal.messages.nano.SystemMessageProto; import com.android.internal.widget.LockscreenCredential; import com.android.server.LocalServices; import com.android.server.SystemService; @@ -103,6 +106,7 @@ import com.android.server.devicepolicy.DevicePolicyManagerService.RestrictionsLi import org.hamcrest.BaseMatcher; import org.hamcrest.Description; +import org.hamcrest.Matcher; import org.mockito.Mockito; import org.mockito.internal.util.collections.Sets; import org.mockito.stubbing.Answer; @@ -181,6 +185,20 @@ public class DevicePolicyManagerTest extends DpmTestBase { "wQ==\n" + "-----END CERTIFICATE-----\n"; + // Constants for testing setManagedProfileMaximumTimeOff: + // Profile maximum time off value + private static final long PROFILE_OFF_TIMEOUT = TimeUnit.DAYS.toMillis(5); + // Synthetic time at the beginning of test. + private static final long PROFILE_OFF_START = 1; + // Time when warning notification should be posted, + private static final long PROFILE_OFF_WARNING_TIME = + PROFILE_OFF_START + PROFILE_OFF_TIMEOUT - TimeUnit.DAYS.toMillis(1); + // Time when the apps should be suspended + private static final long PROFILE_OFF_DEADLINE = PROFILE_OFF_START + PROFILE_OFF_TIMEOUT; + // Notification titles for setManagedProfileMaximumTimeOff tests: + private static final String PROFILE_OFF_WARNING_TITLE = "suspended_tomorrow"; + private static final String PROFILE_OFF_SUSPENDED_TITLE = "suspended"; + @Override protected void setUp() throws Exception { super.setUp(); @@ -1558,20 +1576,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { dpms.approveCaCert(fourCerts.getList().get(1), userId, true); // a notification should be shown saying that there are two certificates left to approve. verify(getServices().notificationManager, timeout(1000)) - .notifyAsUser(anyString(), anyInt(), argThat( - new BaseMatcher<Notification>() { - @Override - public boolean matches(Object item) { - final Notification noti = (Notification) item; - return TEST_STRING.equals( - noti.extras.getString(Notification.EXTRA_TITLE)); - } - @Override - public void describeTo(Description description) { - description.appendText( - "Notification{title=\"" + TEST_STRING + "\"}"); - } - }), eq(user)); + .notifyAsUser(anyString(), anyInt(), argThat(hasTitle(TEST_STRING)), eq(user)); } /** @@ -6272,7 +6277,214 @@ public class DevicePolicyManagerTest extends DpmTestBase { assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty(); } - // admin1 is the outgoing DPC, adminAnotherPakcage is the incoming one. + /** + * Tests the case when the user doesn't turn the profile on in time, verifies that the user is + * warned with a notification and then the apps get suspended. + */ + public void testMaximumProfileTimeOff_profileOffTimeExceeded() throws Exception { + prepareMocksForSetMaximumProfileTimeOff(); + + mContext.binder.callingUid = DpmMockContext.CALLER_UID; + dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT); + + mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; + // The profile is running, neither alarm nor notification should be posted. + verify(getServices().alarmManager, never()) + .set(anyInt(), anyLong(), any(PendingIntent.class)); + verify(getServices().notificationManager, never()) + .notify(anyInt(), any(Notification.class)); + // Apps shouldn't be suspended. + verifyZeroInteractions(getServices().ipackageManager); + clearInvocations(getServices().alarmManager); + + sendUserStoppedBroadcastForProfile(); + + // Verify the alarm was scheduled for time when the warning should be shown. + verify(getServices().alarmManager, times(1)) + .set(anyInt(), eq(PROFILE_OFF_WARNING_TIME), any()); + // But still no notification should be posted at this point. + verify(getServices().notificationManager, never()) + .notify(anyInt(), any(Notification.class)); + // Apps shouldn't be suspended. + verifyZeroInteractions(getServices().ipackageManager); + clearInvocations(getServices().alarmManager); + + // Pretend the alarm went off. + dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_WARNING_TIME + 10); + sendProfileOffDeadlineAlarmBroadcast(); + + // Verify the alarm was scheduled for the actual deadline this time. + verify(getServices().alarmManager, times(1)).set(anyInt(), eq(PROFILE_OFF_DEADLINE), any()); + // Now the user should see a warning notification. + verify(getServices().notificationManager, times(1)) + .notify(anyInt(), argThat(hasTitle(PROFILE_OFF_WARNING_TITLE))); + // Apps shouldn't be suspended yet. + verifyZeroInteractions(getServices().ipackageManager); + clearInvocations(getServices().alarmManager); + clearInvocations(getServices().notificationManager); + + // Pretend the alarm went off. + dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_DEADLINE + 10); + sendProfileOffDeadlineAlarmBroadcast(); + + // Verify the alarm was not set. + verifyZeroInteractions(getServices().alarmManager); + // Now the user should see a notification about suspended apps. + verify(getServices().notificationManager, times(1)) + .notify(anyInt(), argThat(hasTitle(PROFILE_OFF_SUSPENDED_TITLE))); + // Verify that the apps are suspended. + verify(getServices().ipackageManager, times(1)).setPackagesSuspendedAsUser( + any(), eq(true), any(), any(), any(), any(), anyInt()); + } + + /** + * Tests the case when the user turns the profile back on long before the deadline (> 1 day). + */ + public void testMaximumProfileTimeOff_turnOnBeforeWarning() throws Exception { + prepareMocksForSetMaximumProfileTimeOff(); + + mContext.binder.callingUid = DpmMockContext.CALLER_UID; + dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT); + + mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; + sendUserStoppedBroadcastForProfile(); + clearInvocations(getServices().alarmManager); + sendUserUnlockedBroadcastForProfile(); + + // Verify that the alarm got discharged. + verify(getServices().alarmManager, times(1)).cancel((PendingIntent) null); + } + + /** + * Tests the case when the user turns the profile back on after the warning notification. + */ + public void testMaximumProfileTimeOff_turnOnAfterWarning() throws Exception { + prepareMocksForSetMaximumProfileTimeOff(); + + mContext.binder.callingUid = DpmMockContext.CALLER_UID; + dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT); + + mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; + sendUserStoppedBroadcastForProfile(); + + // Pretend the alarm went off. + dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_WARNING_TIME + 10); + sendProfileOffDeadlineAlarmBroadcast(); + + clearInvocations(getServices().alarmManager); + clearInvocations(getServices().notificationManager); + sendUserUnlockedBroadcastForProfile(); + + // Verify that the alarm got discharged. + verify(getServices().alarmManager, times(1)).cancel((PendingIntent) null); + // Verify that the notification is removed. + verify(getServices().notificationManager, times(1)) + .cancel(eq(SystemMessageProto.SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED)); + } + + /** + * Tests the case when the user turns the profile back on when the apps are already suspended. + */ + public void testMaximumProfileTimeOff_turnOnAfterDeadline() throws Exception { + prepareMocksForSetMaximumProfileTimeOff(); + + mContext.binder.callingUid = DpmMockContext.CALLER_UID; + dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT); + + mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; + sendUserStoppedBroadcastForProfile(); + + // Pretend the alarm went off after the deadline. + dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_DEADLINE + 10); + sendProfileOffDeadlineAlarmBroadcast(); + + clearInvocations(getServices().alarmManager); + clearInvocations(getServices().notificationManager); + clearInvocations(getServices().ipackageManager); + + sendUserUnlockedBroadcastForProfile(); + + // Verify that the notification is removed (at this point DPC should show it). + verify(getServices().notificationManager, times(1)) + .cancel(eq(SystemMessageProto.SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED)); + // Verify that the apps are NOT unsuspeded. + verify(getServices().ipackageManager, never()).setPackagesSuspendedAsUser( + any(), eq(false), any(), any(), any(), any(), anyInt()); + } + + private void sendUserUnlockedBroadcastForProfile() throws Exception { + when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE))) + .thenReturn(true); + final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED) + .putExtra(Intent.EXTRA_USER_HANDLE, DpmMockContext.CALLER_USER_HANDLE); + getServices().injectBroadcast( + mServiceContext, unlockedIntent, DpmMockContext.CALLER_USER_HANDLE); + flushTasks(); + } + + + private void sendProfileOffDeadlineAlarmBroadcast() throws Exception { + final Intent deadlineAlarmIntent = + new Intent(DevicePolicyManagerService.ACTION_PROFILE_OFF_DEADLINE); + getServices().injectBroadcast( + mServiceContext, deadlineAlarmIntent, DpmMockContext.CALLER_USER_HANDLE); + flushTasks(); + } + + private void sendUserStoppedBroadcastForProfile() throws Exception { + when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE))) + .thenReturn(false); + final Intent stoppedIntent = new Intent(Intent.ACTION_USER_STOPPED) + .putExtra(Intent.EXTRA_USER_HANDLE, DpmMockContext.CALLER_USER_HANDLE); + getServices().injectBroadcast(mServiceContext, stoppedIntent, + DpmMockContext.CALLER_USER_HANDLE); + flushTasks(); + } + + private void prepareMocksForSetMaximumProfileTimeOff() throws Exception { + addManagedProfile(admin1, DpmMockContext.CALLER_UID, admin1); + configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE); + + when(getServices().userManager.isUserUnlocked()).thenReturn(true); + + // Pretend our admin handles CHECK_POLICY_COMPLIANCE intent. + final Intent intent = new Intent(DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE); + intent.setPackage(admin1.getPackageName()); + + doReturn(Collections.singletonList(new ResolveInfo())) + .when(getServices().packageManager).queryIntentActivitiesAsUser( + any(Intent.class), anyInt(), eq(DpmMockContext.CALLER_USER_HANDLE)); + + dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_START); + // To allow creation of Notification via Notification.Builder + mContext.applicationInfo = mRealTestContext.getApplicationInfo(); + + // Setup notification titles. + when(mServiceContext.resources + .getString(R.string.personal_apps_suspended_tomorrow_title)) + .thenReturn(PROFILE_OFF_WARNING_TITLE); + when(mServiceContext.resources + .getString(R.string.personal_apps_suspended_title)) + .thenReturn(PROFILE_OFF_SUSPENDED_TITLE); + + clearInvocations(getServices().ipackageManager); + } + + private static Matcher<Notification> hasTitle(String expected) { + return new BaseMatcher<Notification>() { + @Override + public boolean matches(Object item) { + final Notification notification = (Notification) item; + return expected.equals(notification.extras.getString(Notification.EXTRA_TITLE)); + } + @Override + public void describeTo(Description description) { + description.appendText("Notification{title=\"" + expected + "\"}"); + } + }; + } + + // admin1 is the outgoing DPC, adminAnotherPackage is the incoming one. private void assertDeviceOwnershipRevertedWithFakeTransferMetadata() throws Exception { writeFakeTransferMetadataFile(UserHandle.USER_SYSTEM, TransferOwnershipMetadataManager.ADMIN_TYPE_DEVICE_OWNER); @@ -6299,7 +6511,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { mServiceContext.binder.restoreCallingIdentity(ident); } - // admin1 is the outgoing DPC, adminAnotherPakcage is the incoming one. + // admin1 is the outgoing DPC, adminAnotherPackage is the incoming one. private void assertProfileOwnershipRevertedWithFakeTransferMetadata() throws Exception { writeFakeTransferMetadataFile(DpmMockContext.CALLER_USER_HANDLE, TransferOwnershipMetadataManager.ADMIN_TYPE_PROFILE_OWNER); diff --git a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java index 7b3417a67857..b69cc47ba738 100644 --- a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java @@ -107,9 +107,10 @@ public class AutomaticBrightnessControllerTest { eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class)); SensorEventListener listener = listenerCaptor.getValue(); - // Set up system to return 5 as a brightness value + // Set up system to return 0.02f as a brightness value float lux1 = 100.0f; - float normalizedBrightness1 = 0.0158f; //float equivalent of 5 out of 255 + // Brightness as float (from 0.0f to 1.0f) + float normalizedBrightness1 = 0.02f; when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux1)) .thenReturn(lux1); when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux1)) @@ -120,14 +121,14 @@ public class AutomaticBrightnessControllerTest { // This is the important bit: When the new brightness is set, make sure the new // brightening threshold is beyond the maximum brightness value...so that we can test that // our threshold clamping works. - when(mScreenBrightnessThresholds.getBrighteningThreshold(5)).thenReturn(1.0f); + when(mScreenBrightnessThresholds.getBrighteningThreshold(normalizedBrightness1)) + .thenReturn(1.0f); // Send new sensor value and verify listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux1)); - assertEquals(5, controller.getAutomaticScreenBrightness()); + assertEquals(normalizedBrightness1, controller.getAutomaticScreenBrightness(), 0.001f); - - // Set up system to return 255 as a brightness value + // Set up system to return 0.0f (minimum possible brightness) as a brightness value float lux2 = 10.0f; float normalizedBrightness2 = 0.0f; when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux2)) @@ -139,7 +140,7 @@ public class AutomaticBrightnessControllerTest { // Send new sensor value and verify listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux2)); - assertEquals(1, controller.getAutomaticScreenBrightness()); + assertEquals(normalizedBrightness2, controller.getAutomaticScreenBrightness(), 0.001f); } @Test @@ -153,9 +154,9 @@ public class AutomaticBrightnessControllerTest { eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class)); SensorEventListener listener = listenerCaptor.getValue(); - // Set up system to return 250 as a brightness value + // Set up system to return 0.98f as a brightness value float lux1 = 100.0f; - float normalizedBrightness1 = 0.981f; //float equivalent of 250 out of 255 + float normalizedBrightness1 = 0.98f; when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux1)) .thenReturn(lux1); when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux1)) @@ -166,14 +167,15 @@ public class AutomaticBrightnessControllerTest { // This is the important bit: When the new brightness is set, make sure the new // brightening threshold is beyond the maximum brightness value...so that we can test that // our threshold clamping works. - when(mScreenBrightnessThresholds.getBrighteningThreshold(250)).thenReturn(260.0f); + when(mScreenBrightnessThresholds.getBrighteningThreshold(normalizedBrightness1)) + .thenReturn(1.1f); // Send new sensor value and verify listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux1)); - assertEquals(250, controller.getAutomaticScreenBrightness()); + assertEquals(normalizedBrightness1, controller.getAutomaticScreenBrightness(), 0.001f); - // Set up system to return 255 as a brightness value + // Set up system to return 1.0f as a brightness value (brightness_max) float lux2 = 110.0f; float normalizedBrightness2 = 1.0f; when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux2)) @@ -185,7 +187,7 @@ public class AutomaticBrightnessControllerTest { // Send new sensor value and verify listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux2)); - assertEquals(255, controller.getAutomaticScreenBrightness()); + assertEquals(normalizedBrightness2, controller.getAutomaticScreenBrightness(), 0.001f); } @Test @@ -204,10 +206,10 @@ public class AutomaticBrightnessControllerTest { // User sets brightness to 100 controller.configure(true /* enable */, null /* configuration */, - 100 /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */, + 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT); // There should be a user data point added to the mapper. - verify(mBrightnessMappingStrategy).addUserDataPoint(1000f, 100); + verify(mBrightnessMappingStrategy).addUserDataPoint(1000f, 0.5f); } } diff --git a/services/tests/servicestests/src/com/android/server/emergency/EmergencyAffordanceServiceTest.java b/services/tests/servicestests/src/com/android/server/emergency/EmergencyAffordanceServiceTest.java new file mode 100644 index 000000000000..d438a0eb9411 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/emergency/EmergencyAffordanceServiceTest.java @@ -0,0 +1,486 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.emergency; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.os.UserHandle; +import android.provider.Settings; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; +import android.telephony.TelephonyManager; +import android.test.mock.MockContentResolver; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.InstrumentationRegistry; + +import com.android.internal.util.test.BroadcastInterceptingContext; +import com.android.internal.util.test.FakeSettingsProvider; +import com.android.server.SystemService; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +/** + * Unit test for EmergencyAffordanceService (EAS for short) which determines when + * should we enable Emergency Affordance feature (EA for short). + * + * Please refer to https://source.android.com/devices/tech/connect/emergency-affordance + * to see the details of the feature. + */ +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class EmergencyAffordanceServiceTest { + + // Default country ISO that should enable EA. Value comes from resource + // com.android.internal.R.array.config_emergency_iso_country_codes + private static final String EMERGENCY_ISO_CODE = "in"; + // Randomly picked country ISO that should not enable EA. + private static final String NON_EMERGENCY_ISO_CODE = "us"; + + // Valid values for Settings.Global.EMERGENCY_AFFORDANCE_NEEDED + private static final int OFF = 0; // which means feature disabled + private static final int ON = 1; // which means feature enabled + + private static final int ACTIVE_MODEM_COUNT = 2; + + @Mock private Resources mResources; + @Mock private SubscriptionManager mSubscriptionManager; + @Mock private TelephonyManager mTelephonyManager; + + private TestContext mServiceContext; + private MockContentResolver mContentResolver; + private OnSubscriptionsChangedListener mSubscriptionChangedListener; + private EmergencyAffordanceService mService; + + // Testable Context that mocks resources, content resolver and system services + private class TestContext extends BroadcastInterceptingContext { + TestContext(Context base) { + super(base); + } + + @Override + public ContentResolver getContentResolver() { + return mContentResolver; + } + + @Override + public Resources getResources() { + return mResources; + } + + @Override + public Object getSystemService(String name) { + switch (name) { + case Context.TELEPHONY_SUBSCRIPTION_SERVICE: + return mSubscriptionManager; + case Context.TELEPHONY_SERVICE: + return mTelephonyManager; + default: + return super.getSystemService(name); + } + } + } + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + doReturn(new String[] { EMERGENCY_ISO_CODE }).when(mResources) + .getStringArray(com.android.internal.R.array.config_emergency_iso_country_codes); + + final Context context = InstrumentationRegistry.getContext(); + mServiceContext = new TestContext(context); + mContentResolver = new MockContentResolver(mServiceContext); + mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); + + // Initialize feature off, to have constant starting + Settings.Global.putInt(mContentResolver, Settings.Global.EMERGENCY_AFFORDANCE_NEEDED, 0); + mService = new EmergencyAffordanceService(mServiceContext); + } + + /** + * Verify if the device is not voice capable, the feature should be disabled. + */ + @Test + public void testSettings_shouldBeOff_whenVoiceCapableIsFalse() throws Exception { + // Given: the device is not voice capable + // When: setup device and boot service + setUpDevice(false /* withVoiceCapable */, true /* withEmergencyIsoInSim */, + true /* withEmergencyIsoInCell */); + + // Then: EA setting will should be 0 + verifyEmergencyAffordanceNeededSettings(OFF); + } + + /** + * Verify the voice capable device is booted up without EA-enabled cell network, with + * no EA-enabled SIM installed, feature should be disabled. + */ + @Test + public void testSettings_shouldBeOff_whenWithoutEAEanbledNetworkNorSim() throws Exception { + // Given: the device is voice capble, no EA-enable SIM, no EA-enabled Cell + setUpDevice(true /* withVoiceCapable */, false /* withEmergencyIsoInSim */, + false /* withEmergencyIsoInCell */); + + // Then: EA setting will should be 0 + verifyEmergencyAffordanceNeededSettings(OFF); + } + + /** + * Verify the voice capable device is booted up with EA-enabled SIM installed, the + * feature should be enabled. + */ + @Test + public void testSettings_shouldBeOn_whenBootUpWithEAEanbledSim() throws Exception { + // Given: the device is voice capble, with EA-enable SIM, no EA-enabled Cell + setUpDevice(true /* withVoiceCapable */, true /* withEmergencyIsoInSim */, + false /* withEmergencyIsoInCell */); + + // Then: EA setting will immediately update to 1 + verifyEmergencyAffordanceNeededSettings(ON); + } + + /** + * Verify the voice capable device is booted up with EA-enabled Cell network, the + * feature should be enabled. + */ + @Test + public void testSettings_shouldBeOn_whenBootUpWithEAEanbledCell() throws Exception { + // Given: the device is voice capble, with EA-enable SIM, with EA-enabled Cell + setUpDevice(true /* withVoiceCapable */, false /* withEmergencyIsoInSim */, + true /* withEmergencyIsoInCell */); + + // Then: EA setting will immediately update to 1 + verifyEmergencyAffordanceNeededSettings(ON); + } + + /** + * Verify when device boot up with no EA-enabled SIM, but later install one, + * feature should be enabled. + */ + @Test + public void testSettings_shouldBeOn_whenSubscriptionInfoChangedWithEmergencyIso() + throws Exception { + // Given: the device is voice capable, boot up with no EA-enabled SIM, no EA-enabled Cell + setUpDevice(true /* withVoiceCapable */, false/* withEmergencyIsoInSim */, + false /* withEmergencyIsoInCell */); + + // When: Insert EA-enabled SIM and get notified + setUpSim(true /* withEmergencyIsoInSim */); + mSubscriptionChangedListener.onSubscriptionsChanged(); + + // Then: EA Setting will update to 1 + verifyEmergencyAffordanceNeededSettings(ON); + } + + /** + * Verify when feature was on, device re-insert with no EA-enabled SIMs, + * feature should be disabled. + */ + @Test + public void testSettings_shouldBeOff_whenSubscriptionInfoChangedWithoutEmergencyIso() + throws Exception { + // Given: the device is voice capable, no EA-enabled Cell, with EA-enabled SIM + setUpDevice(true /* withVoiceCapable */, true /* withEmergencyIsoInSim */, + false /* withEmergencyIsoInCell */); + + // When: All SIMs are replaced with EA-disabled ones. + setUpSim(false /* withEmergencyIsoInSim */); + mSubscriptionChangedListener.onSubscriptionsChanged(); + + // Then: EA Setting will update to 0 + verifyEmergencyAffordanceNeededSettings(OFF); + } + + /** + * Verify when device boot up with no EA-enabled Cell, but later move into one, + * feature should be enabled. + */ + @Test + public void testSettings_shouldBeOn_whenCountryIsoChangedWithEmergencyIso() + throws Exception { + // Given: the device is voice capable, boot up with no EA-enabled SIM, no EA-enabled Cell + setUpDevice(true /* withVoiceCapable */, false/* withEmergencyIsoInSim */, + false /* withEmergencyIsoInCell */); + + // When: device locale change to EA-enabled Cell and get notified + resetCell(true /* withEmergencyIsoInSim */); + sendBroadcastNetworkCountryChanged(EMERGENCY_COUNTRY_ISO); + + // Then: EA Setting will update to 1 + verifyEmergencyAffordanceNeededSettings(ON); + } + + /** + * Verify when device boot up with EA-enabled Cell, but later move out of it, + * feature should be enabled. + */ + @Test + public void testSettings_shouldBeOff_whenCountryIsoChangedWithoutEmergencyIso() + throws Exception { + // Given: the device is voice capable, boot up with no EA-enabled SIM, with EA-enabled Cell + setUpDevice(true /* withVoiceCapable */, false/* withEmergencyIsoInSim */, + true /* withEmergencyIsoInCell */); + + // When: device locale change to no EA-enabled Cell and get notified + resetCell(false /* withEmergencyIsoInSim */); + sendBroadcastNetworkCountryChanged(NON_EMERGENCY_COUNTRY_ISO); + + // Then: EA Setting will update to 0 + verifyEmergencyAffordanceNeededSettings(OFF); + } + /** + * Verify if device is not in EA-enabled Mobile Network without EA-enable SIM(s) installed, + * when receive SubscriptionInfo change, the feature should not be enabled. + */ + @Test + public void testSettings_shouldBeOff_whenNoEmergencyIsoInCellNorSim() throws Exception { + // Given: the device is voice capable, no EA-enabled Cell, no EA-enabled SIM + setUpDevice(true /* withVoiceCapable */, false /* withEmergencyIsoInSim */, + false /* withEmergencyIsoInCell */); + + // When: Subscription changed event received + mSubscriptionChangedListener.onSubscriptionsChanged(); + + // Then: EA Settings should be 0 + verifyEmergencyAffordanceNeededSettings(OFF); + } + + /** + * Verify while feature was on, when device receive empty country iso change, while APM is + * enabled, feature status should keep on. + */ + @Test + public void testSettings_shouldOn_whenReceiveEmptyISOWithAPMEnabled() throws Exception { + // Given: the device is voice capable, no EA-enabled SIM, with EA-enabled Cell + setUpDevice(true /* withVoiceCapable */, false /* withEmergencyIsoInSim */, + true /* withEmergencyIsoInCell */); + + // Then: EA Settings will update to 1 + verifyEmergencyAffordanceNeededSettings(ON); + + // When: Airplane mode is enabled, and we receive EMPTY ISO in locale change + setAirplaneMode(true); + sendBroadcastNetworkCountryChanged(EMPTY_COUNTRY_ISO); + + // Then: EA Settings will keep to 1 + verifyEmergencyAffordanceNeededSettings(ON); + } + + /** + * Verify while feature was on, when device receive empty country iso change, while APM is + * disabled, feature should be disabled. + */ + @Test + public void testSettings_shouldOff_whenReceiveEmptyISOWithAPMDisabled() throws Exception { + // Given: the device is voice capable, no EA-enabled SIM, with EA-enabled Cell + setUpDevice(true /* withVoiceCapable */, false /* withEmergencyIsoInSim */, + true /* withEmergencyIsoInCell */); + + // Then: EA Settings will update to 1 + verifyEmergencyAffordanceNeededSettings(ON); + + // When: Airplane mode is disabled, and we receive valid empty ISO in locale change + setUpCell(false /* withEmergencyIsoInCell */); + setAirplaneMode(false); + sendBroadcastNetworkCountryChanged(EMPTY_COUNTRY_ISO); + + // Then: EA Settings will keep to 0 + verifyEmergencyAffordanceNeededSettings(OFF); + } + + /** + * Verify when airplane mode is turn on and off in cell network with EA-enabled ISO, + * feature should keep enabled. + */ + @Test + public void testSettings_shouldBeOn_whenAirplaneModeOnOffWithEmergencyIsoInCell() + throws Exception { + // Given: the device is voice capable, no EA-enabled SIM, with EA-enabled Cell + setUpDevice(true /* withVoiceCapable */, false /* withEmergencyIsoInSim */, + true /* withEmergencyIsoInCell */); + + // When: Device receive locale change with EA-enabled iso + sendBroadcastNetworkCountryChanged(EMERGENCY_COUNTRY_ISO); + + // When: Airplane mode is disabled + setAirplaneMode(false); + + // Then: EA Settings will keep with 1 + verifyEmergencyAffordanceNeededSettings(ON); + + // When: Airplane mode is enabled + setAirplaneMode(true); + + // Then: EA Settings is still 1 + verifyEmergencyAffordanceNeededSettings(ON); + } + + /** + * Verify when airplane mode is turn on and off with EA-enabled ISO in SIM, + * feature should keep enabled. + */ + @Test + public void testSettings_shouldBeOn_whenAirplaneModeOnOffWithEmergencyIsoInSim() + throws Exception { + // Given: the device is voice capable, no EA-enabled Cell Network, with EA-enabled SIM + setUpDevice(true /* withVoiceCapable */, true /* withEmergencyIsoInSim */, + false /* withEmergencyIsoInCell */); + + // When: Airplane mode is disabled + setAirplaneMode(false); + + // Then: EA Settings will keep with 1 + verifyEmergencyAffordanceNeededSettings(ON); + + // When: Airplane mode is enabled + setAirplaneMode(true); + + // Then: EA Settings is still 1 + verifyEmergencyAffordanceNeededSettings(ON); + } + + // EAS reads voice capable during boot up and cache it. To test non voice capable device, + // we can not put this in setUp + private void setUpDevice(boolean withVoiceCapable, boolean withEmergencyIsoInSim, + boolean withEmergencyIsoInCell) throws Exception { + setUpVoiceCapable(withVoiceCapable); + + setUpSim(withEmergencyIsoInSim); + + setUpCell(withEmergencyIsoInCell); + + // bypass onStart which is used to publish binder service and need sepolicy policy update + // mService.onStart(); + + mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); + + if (!withVoiceCapable) { + return; + } + + captureSubscriptionChangeListener(); + } + + private void setUpVoiceCapable(boolean voiceCapable) { + doReturn(voiceCapable).when(mTelephonyManager).isVoiceCapable(); + } + + private static final Supplier<String> EMPTY_COUNTRY_ISO = () -> ""; + private static final Supplier<String> EMERGENCY_COUNTRY_ISO = () -> EMERGENCY_ISO_CODE; + private static final Supplier<String> NON_EMERGENCY_COUNTRY_ISO = () -> NON_EMERGENCY_ISO_CODE; + private void sendBroadcastNetworkCountryChanged(Supplier<String> countryIso) { + Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED); + intent.putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, countryIso.get()); + SubscriptionManager.putPhoneIdAndSubIdExtra(intent, 0); + mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL); + } + + private void setUpSim(boolean withEmergencyIsoInSim) { + List<SubscriptionInfo> subInfos = getSubscriptionInfoList(withEmergencyIsoInSim); + doReturn(subInfos).when(mSubscriptionManager).getActiveSubscriptionInfoList(); + } + + private void setUpCell(boolean withEmergencyIsoInCell) { + doReturn(ACTIVE_MODEM_COUNT).when(mTelephonyManager).getActiveModemCount(); + doReturn(NON_EMERGENCY_ISO_CODE).when(mTelephonyManager).getNetworkCountryIso(0); + doReturn(withEmergencyIsoInCell ? EMERGENCY_ISO_CODE : NON_EMERGENCY_ISO_CODE) + .when(mTelephonyManager).getNetworkCountryIso(1); + } + + private void resetCell(boolean withEmergencyIsoInCell) { + doReturn(withEmergencyIsoInCell ? EMERGENCY_ISO_CODE : NON_EMERGENCY_ISO_CODE) + .when(mTelephonyManager).getNetworkCountryIso(1); + } + + private void captureSubscriptionChangeListener() { + final ArgumentCaptor<OnSubscriptionsChangedListener> subChangedListenerCaptor = + ArgumentCaptor.forClass(OnSubscriptionsChangedListener.class); + verify(mSubscriptionManager).addOnSubscriptionsChangedListener( + subChangedListenerCaptor.capture()); + mSubscriptionChangedListener = subChangedListenerCaptor.getValue(); + } + + private void setAirplaneMode(boolean enabled) { + // Change the system settings + Settings.Global.putInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON, + enabled ? 1 : 0); + + // Post the intent + final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); + intent.putExtra("state", enabled); + mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL); + } + + private List<SubscriptionInfo> getSubscriptionInfoList(boolean withEmergencyIso) { + List<SubscriptionInfo> subInfos = new ArrayList<>(2); + + // Test with Multiple SIMs. SIM1 is a non-EA SIM + // Only country iso is valuable, all other info are filled with dummy values + SubscriptionInfo subInfo = new SubscriptionInfo(1, "890126042XXXXXXXXXXX", 0, "T-mobile", + "T-mobile", 0, 255, "12345", 0, null, + "310", "226", NON_EMERGENCY_ISO_CODE, false, null, null); + subInfos.add(subInfo); + + // SIM2 can configured to be non-EA or EA SIM according parameter withEmergencyIso + SubscriptionInfo subInfo2 = new SubscriptionInfo(1, "890126042XXXXXXXXXXX", 0, "Airtel", + "Aritel", 0, 255, "12345", 0, null, "310", "226", + withEmergencyIso ? EMERGENCY_ISO_CODE : NON_EMERGENCY_ISO_CODE, + false, null, null); + subInfos.add(subInfo2); + + return subInfos; + } + + // EAS has handler thread to perform heavy work, while FakeSettingProvider does not support + // ContentObserver. To make sure consistent result, we use a simple sleep & retry to wait for + // real work finished before verify result. + private static final int TIME_DELAY_BEFORE_VERIFY_IN_MS = 50; + private static final int RETRIES_BEFORE_VERIFY = 20; + private void verifyEmergencyAffordanceNeededSettings(int expected) throws Exception { + try { + int ct = 0; + int actual = -1; + while (ct++ < RETRIES_BEFORE_VERIFY + && (actual = Settings.Global.getInt(mContentResolver, + Settings.Global.EMERGENCY_AFFORDANCE_NEEDED)) != expected) { + Thread.sleep(TIME_DELAY_BEFORE_VERIFY_IN_MS); + } + assertEquals(expected, actual); + } catch (Settings.SettingNotFoundException e) { + fail("SettingNotFoundException thrown for Settings.Global.EMERGENCY_AFFORDANCE_NEEDED"); + } + } +} diff --git a/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java b/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java index 70d6cf81c3b0..ea8aa6bb5c03 100644 --- a/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java +++ b/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java @@ -54,6 +54,7 @@ public final class ConversationInfoTest { .setPersonImportant(true) .setPersonBot(true) .setContactStarred(true) + .setNotificationSettingChanged(true) .build(); assertEquals(SHORTCUT_ID, conversationInfo.getShortcutId()); @@ -70,6 +71,7 @@ public final class ConversationInfoTest { assertTrue(conversationInfo.isPersonImportant()); assertTrue(conversationInfo.isPersonBot()); assertTrue(conversationInfo.isContactStarred()); + assertTrue(conversationInfo.isNotificationSettingChanged()); } @Test @@ -92,6 +94,7 @@ public final class ConversationInfoTest { assertFalse(conversationInfo.isPersonImportant()); assertFalse(conversationInfo.isPersonBot()); assertFalse(conversationInfo.isContactStarred()); + assertFalse(conversationInfo.isNotificationSettingChanged()); } @Test @@ -109,6 +112,7 @@ public final class ConversationInfoTest { .setPersonImportant(true) .setPersonBot(true) .setContactStarred(true) + .setNotificationSettingChanged(true) .build(); ConversationInfo destination = new ConversationInfo.Builder(source) @@ -128,5 +132,6 @@ public final class ConversationInfoTest { assertTrue(destination.isPersonImportant()); assertTrue(destination.isPersonBot()); assertFalse(destination.isContactStarred()); + assertTrue(destination.isNotificationSettingChanged()); } } diff --git a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java index e16f3145de0b..e51ab9dbdd9b 100644 --- a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java @@ -34,6 +34,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -407,6 +408,7 @@ public final class DataManagerTest { ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, buildPerson()); + shortcut.setCached(); mDataManager.addOrUpdateConversationInfo(shortcut); NotificationListenerService listenerService = @@ -418,6 +420,68 @@ public final class DataManagerTest { List<Range<Long>> activeNotificationOpenTimeSlots = getActiveSlotsForTestShortcut( Event.NOTIFICATION_EVENT_TYPES); assertEquals(1, activeNotificationOpenTimeSlots.size()); + verify(mShortcutServiceInternal).uncacheShortcuts( + anyInt(), any(), eq(TEST_PKG_NAME), + eq(Collections.singletonList(TEST_SHORTCUT_ID)), eq(USER_ID_PRIMARY)); + } + + @Test + public void testNotificationDismissed() { + mDataManager.onUserUnlocked(USER_ID_PRIMARY); + + ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, + buildPerson()); + mDataManager.addOrUpdateConversationInfo(shortcut); + + NotificationListenerService listenerService = + mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); + + // Post one notification. + shortcut.setCached(); + mDataManager.addOrUpdateConversationInfo(shortcut); + listenerService.onNotificationPosted(mStatusBarNotification); + + // Post another notification. + listenerService.onNotificationPosted(mStatusBarNotification); + + // Removing one of the two notifications does not un-cache the shortcut. + listenerService.onNotificationRemoved(mStatusBarNotification, null, + NotificationListenerService.REASON_CANCEL); + verify(mShortcutServiceInternal, never()).uncacheShortcuts( + anyInt(), any(), anyString(), any(), anyInt()); + + // Removing the second notification un-caches the shortcut. + listenerService.onNotificationRemoved(mStatusBarNotification, null, + NotificationListenerService.REASON_CANCEL_ALL); + verify(mShortcutServiceInternal).uncacheShortcuts( + anyInt(), any(), eq(TEST_PKG_NAME), + eq(Collections.singletonList(TEST_SHORTCUT_ID)), eq(USER_ID_PRIMARY)); + } + + @Test + public void testShortcutNotUncachedIfSettingChanged() { + mDataManager.onUserUnlocked(USER_ID_PRIMARY); + + ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, + buildPerson()); + mDataManager.addOrUpdateConversationInfo(shortcut); + + NotificationListenerService listenerService = + mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY); + + listenerService.onNotificationPosted(mStatusBarNotification); + shortcut.setCached(); + mDataManager.addOrUpdateConversationInfo(shortcut); + + mNotificationChannel.setImportantConversation(true); + listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY), + mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED); + + listenerService.onNotificationRemoved(mStatusBarNotification, null, + NotificationListenerService.REASON_CANCEL_ALL); + verify(mShortcutServiceInternal, never()).uncacheShortcuts( + anyInt(), any(), eq(TEST_PKG_NAME), + eq(Collections.singletonList(TEST_SHORTCUT_ID)), eq(USER_ID_PRIMARY)); } @Test @@ -466,9 +530,7 @@ public final class DataManagerTest { assertTrue(conversationInfo.isImportant()); assertFalse(conversationInfo.isNotificationSilenced()); assertFalse(conversationInfo.isDemoted()); - verify(mShortcutServiceInternal).cacheShortcuts( - anyInt(), any(), eq(TEST_PKG_NAME), - eq(Collections.singletonList(TEST_SHORTCUT_ID)), eq(USER_ID_PRIMARY)); + assertTrue(conversationInfo.isNotificationSettingChanged()); } @Test diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java index 69ef499749a9..df92b6ed95e8 100644 --- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java @@ -31,7 +31,6 @@ import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.RemoteException; -import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import com.android.server.twilight.TwilightManager; @@ -55,7 +54,6 @@ import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertTrue; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; @@ -146,7 +144,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { addLocalService(PowerManagerInternal.class, mLocalPowerManager); addLocalService(TwilightManager.class, mTwilightManager); - mUiManagerService = new UiModeManagerService(mContext, true); + mUiManagerService = new UiModeManagerService(mContext); try { mUiManagerService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); } catch (SecurityException e) {/* ignore for permission denial */} 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 7a5e2266e62f..41748b8a893b 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -6053,6 +6053,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbles_flagRemoved_whenShortcutRemoved() throws RemoteException { + final String shortcutId = "someshortcutId"; setUpPrefsForBubbles(PKG, mUid, true /* global */, BUBBLE_PREFERENCE_ALL /* app */, @@ -6063,9 +6064,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Messaging notification with shortcut info Notification.BubbleMetadata metadata = - new Notification.BubbleMetadata.Builder("someshortcutId").build(); + new Notification.BubbleMetadata.Builder(shortcutId).build(); Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */, null /* groupKey */, false /* isSummary */); + nb.setShortcutId(shortcutId); nb.setBubbleMetadata(metadata); StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0, nb.build(), new UserHandle(mUid), null, 0); @@ -6075,7 +6077,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { List<ShortcutInfo> shortcutInfos = new ArrayList<>(); ShortcutInfo info = mock(ShortcutInfo.class); when(info.getPackage()).thenReturn(PKG); - when(info.getId()).thenReturn("someshortcutId"); + when(info.getId()).thenReturn(shortcutId); when(info.getUserId()).thenReturn(USER_SYSTEM); when(info.isLongLived()).thenReturn(true); when(info.isEnabled()).thenReturn(true); @@ -6098,6 +6100,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Notification notif = mService.getNotificationRecord(nr.getSbn().getKey()).getNotification(); assertTrue(notif.isBubbleNotification()); + // Make sure the shortcut is cached. + verify(mShortcutServiceInternal).cacheShortcuts( + anyInt(), any(), eq(PKG), eq(Collections.singletonList(shortcutId)), + eq(USER_SYSTEM)); + // Test: Remove the shortcut when(mLauncherApps.getShortcuts(any(), any())).thenReturn(null); launcherAppsCallback.getValue().onShortcutsChanged(PKG, Collections.emptyList(), @@ -6119,6 +6126,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbles_shortcut_stopListeningWhenNotifRemoved() throws RemoteException { + final String shortcutId = "someshortcutId"; setUpPrefsForBubbles(PKG, mUid, true /* global */, BUBBLE_PREFERENCE_ALL /* app */, @@ -6129,9 +6137,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Messaging notification with shortcut info Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder( - "someshortcutId").build(); + shortcutId).build(); Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */, null /* groupKey */, false /* isSummary */); + nb.setShortcutId(shortcutId); nb.setBubbleMetadata(metadata); StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0, nb.build(), new UserHandle(mUid), null, 0); @@ -6141,7 +6150,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { List<ShortcutInfo> shortcutInfos = new ArrayList<>(); ShortcutInfo info = mock(ShortcutInfo.class); when(info.getPackage()).thenReturn(PKG); - when(info.getId()).thenReturn("someshortcutId"); + when(info.getId()).thenReturn(shortcutId); when(info.getUserId()).thenReturn(USER_SYSTEM); when(info.isLongLived()).thenReturn(true); when(info.isEnabled()).thenReturn(true); @@ -6164,6 +6173,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Notification notif = mService.getNotificationRecord(nr.getSbn().getKey()).getNotification(); assertTrue(notif.isBubbleNotification()); + // Make sure the shortcut is cached. + verify(mShortcutServiceInternal).cacheShortcuts( + anyInt(), any(), eq(PKG), eq(Collections.singletonList(shortcutId)), + eq(USER_SYSTEM)); + // Test: Remove the notification mBinderService.cancelNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId()); @@ -6573,4 +6587,16 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { fail(e.getMessage()); } } + + @Test + public void testRecordMessages() throws RemoteException { + NotificationRecord nr = + generateMessageBubbleNotifRecord(mTestNotificationChannel, + "testRecordMessages"); + mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), + nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); + waitForIdle(); + + assertTrue(mBinderService.hasSentMessage(PKG, mUid)); + } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index ac51750f23f8..e11392bde993 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -454,6 +454,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false); mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true); + mHelper.setMessageSent(PKG_P, UID_P); mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE); @@ -469,6 +470,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_O, UID_O)); assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1)); + assertTrue(mHelper.hasSentMessage(PKG_P, UID_P)); + assertFalse(mHelper.hasSentMessage(PKG_N_MR1, UID_N_MR1)); assertEquals(channel1, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false)); compareChannels(channel2, @@ -3142,6 +3145,44 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test + public void testGetConversations_notDemoted() { + String convoId = "convo"; + NotificationChannel messages = + new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT); + mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false); + NotificationChannel calls = + new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT); + mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false); + NotificationChannel p = + new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT); + mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false); + + NotificationChannel channel = + new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT); + channel.setConversationId(messages.getId(), convoId); + mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false); + + NotificationChannel diffConvo = + new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT); + diffConvo.setConversationId(p.getId(), "different convo"); + diffConvo.setDemoted(true); + mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false); + + NotificationChannel channel2 = + new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT); + channel2.setConversationId(calls.getId(), convoId); + channel2.setImportantConversation(true); + mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false); + + List<ConversationChannelWrapper> convos = mHelper.getConversations(false); + + assertEquals(2, convos.size()); + assertTrue(conversationWrapperContainsChannel(convos, channel)); + assertFalse(conversationWrapperContainsChannel(convos, diffConvo)); + assertTrue(conversationWrapperContainsChannel(convos, channel2)); + } + + @Test public void testGetConversations_onlyImportant() { String convoId = "convo"; NotificationChannel messages = @@ -3352,4 +3393,17 @@ public class PreferencesHelperTest extends UiServiceTestCase { .NOTIFICATION_CHANNEL_CONVERSATION_DELETED, mLogger.get(6).event); // Delete Channel channel2 - Conversation A person calls } + + @Test + public void testMessageSent() { + // create package preferences + mHelper.canShowBadge(PKG_P, UID_P); + + // check default value + assertFalse(mHelper.hasSentMessage(PKG_P, UID_P)); + + // change it + mHelper.setMessageSent(PKG_P, UID_P); + assertTrue(mHelper.hasSentMessage(PKG_P, UID_P)); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java index 1debd8c9ffb1..e3bb1b6ca9f3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java @@ -16,6 +16,8 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; @@ -270,6 +272,28 @@ public class ActivityDisplayTests extends ActivityTestsBase { anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FREEFORM); assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop()); assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getStackAt(topPosition - 1)); + + final ActivityStack dreamStack = taskDisplayArea.createStack( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM, true /* onTop */); + assertEquals(taskDisplayArea, dreamStack.getDisplayArea()); + assertTrue(dreamStack.isAlwaysOnTop()); + topPosition = taskDisplayArea.getStackCount() - 1; + // Ensure dream shows above all activities, including PiP + assertEquals(dreamStack, taskDisplayArea.getTopStack()); + assertEquals(pinnedStack, taskDisplayArea.getStackAt(topPosition - 1)); + + final ActivityStack assistStack = taskDisplayArea.createStack( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */); + assertEquals(taskDisplayArea, assistStack.getDisplayArea()); + assertFalse(assistStack.isAlwaysOnTop()); + topPosition = taskDisplayArea.getStackCount() - 1; + + // Ensure Assistant shows as a non-always-on-top activity when config_assistantOnTopOfDream + // is false and on top of everything when true. + final boolean isAssistantOnTop = mContext.getResources() + .getBoolean(com.android.internal.R.bool.config_assistantOnTopOfDream); + assertEquals(assistStack, taskDisplayArea.getStackAt( + isAssistantOnTop ? topPosition : topPosition - 4)); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index 93ded1b6b2f3..6c209e496cf6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -471,23 +471,39 @@ public class ActivityStackTests extends ActivityTestsBase { assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT, splitScreenSecondary2.getVisibility(null /* starting */)); - // Assistant stack shouldn't be visible behind translucent split-screen stack + // Assistant stack shouldn't be visible behind translucent split-screen stack, + // unless it is configured to show on top of everything. doReturn(false).when(assistantStack).isTranslucent(any()); doReturn(true).when(splitScreenPrimary).isTranslucent(any()); doReturn(true).when(splitScreenSecondary2).isTranslucent(any()); splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen"); splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen"); - assertFalse(assistantStack.shouldBeVisible(null /* starting */)); - assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */)); - assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */)); - assertEquals(STACK_VISIBILITY_INVISIBLE, - assistantStack.getVisibility(null /* starting */)); - assertEquals(STACK_VISIBILITY_VISIBLE, - splitScreenPrimary.getVisibility(null /* starting */)); - assertEquals(STACK_VISIBILITY_INVISIBLE, - splitScreenSecondary.getVisibility(null /* starting */)); - assertEquals(STACK_VISIBILITY_VISIBLE, - splitScreenSecondary2.getVisibility(null /* starting */)); + + if (isAssistantOnTop()) { + assertTrue(assistantStack.shouldBeVisible(null /* starting */)); + assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */)); + assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + assistantStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + splitScreenPrimary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + splitScreenSecondary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + splitScreenSecondary2.getVisibility(null /* starting */)); + } else { + assertFalse(assistantStack.shouldBeVisible(null /* starting */)); + assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */)); + assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + assistantStack.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + splitScreenPrimary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_INVISIBLE, + splitScreenSecondary.getVisibility(null /* starting */)); + assertEquals(STACK_VISIBILITY_VISIBLE, + splitScreenSecondary2.getVisibility(null /* starting */)); + } } @Test @@ -927,9 +943,15 @@ public class ActivityStackTests extends ActivityTestsBase { splitScreenSecondary.moveToFront("testSplitScreenMoveToFront"); - assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */)); - assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */)); - assertFalse(assistantStack.shouldBeVisible(null /* starting */)); + if (isAssistantOnTop()) { + assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */)); + assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */)); + assertTrue(assistantStack.shouldBeVisible(null /* starting */)); + } else { + assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */)); + assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */)); + assertFalse(assistantStack.shouldBeVisible(null /* starting */)); + } } private ActivityStack createStandardStackForVisibilityTest(int windowingMode, @@ -1344,6 +1366,11 @@ public class ActivityStackTests extends ActivityTestsBase { anyBoolean()); } + private boolean isAssistantOnTop() { + return mContext.getResources().getBoolean( + com.android.internal.R.bool.config_assistantOnTopOfDream); + } + private void verifyShouldSleepActivities(boolean focusedStack, boolean keyguardGoingAway, boolean displaySleeping, boolean expected) { final DisplayContent display = mock(DisplayContent.class); diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java index 9b7ffd69da15..e8fab2b0243b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java @@ -37,7 +37,6 @@ import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationDefinition; import android.view.RemoteAnimationTarget; -import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import org.junit.Test; @@ -97,7 +96,6 @@ public class AppChangeTransitionTests extends WindowTestsBase { } @Test - @FlakyTest(bugId = 131005232) public void testModeChangeRemoteAnimatorNoSnapshot() { // setup currently defaults to no snapshot. setUpOnDisplay(mDisplayContent); @@ -115,7 +113,6 @@ public class AppChangeTransitionTests extends WindowTestsBase { } @Test - @FlakyTest(bugId = 131005232) public void testCancelPendingChangeOnRemove() { // setup currently defaults to no snapshot. setUpOnDisplay(mDisplayContent); @@ -135,8 +132,7 @@ public class AppChangeTransitionTests extends WindowTestsBase { } @Test - @FlakyTest(bugId = 131005232) - public void testNoChangeWhenMoveDisplay() { + public void testNoChangeOnOldDisplayWhenMoveDisplay() { mDisplayContent.setWindowingMode(WINDOWING_MODE_FULLSCREEN); final DisplayContent dc1 = createNewDisplay(Display.STATE_ON); dc1.setWindowingMode(WINDOWING_MODE_FREEFORM); @@ -151,9 +147,8 @@ public class AppChangeTransitionTests extends WindowTestsBase { assertEquals(WINDOWING_MODE_FULLSCREEN, mTask.getWindowingMode()); - // Make sure we're not waiting for a change animation (no leash) - assertFalse(mTask.isInChangeTransition()); - assertNull(mActivity.mSurfaceFreezer.mSnapshot); + // Make sure the change transition is not the old display + assertFalse(dc1.mChangingContainers.contains(mTask)); waitUntilHandlersIdle(); mActivity.removeImmediately(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java new file mode 100644 index 000000000000..307b40f1b039 --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm; + +import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.graphics.Rect; +import android.os.Binder; +import android.os.RemoteException; +import android.platform.test.annotations.Presubmit; +import android.window.IDisplayAreaOrganizer; + +import androidx.test.filters.SmallTest; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@Presubmit +@RunWith(WindowTestRunner.class) +public class DisplayAreaOrganizerTest extends WindowTestsBase { + + private DisplayArea mTestDisplayArea; + + @Before + public void setUp() { + WindowContainer parentWindow = mDisplayContent.getDefaultTaskDisplayArea().getParent(); + mTestDisplayArea = new DisplayArea(mWm, DisplayArea.Type.ANY, + "TestDisplayArea", FEATURE_VENDOR_FIRST); + parentWindow.addChild(mTestDisplayArea, + parentWindow.mChildren.indexOf(mDisplayContent.getDefaultTaskDisplayArea()) + 1); + } + + @After + public void tearDown() { + mTestDisplayArea.removeImmediately(); + } + + private IDisplayAreaOrganizer registerMockOrganizer(int feature) { + final IDisplayAreaOrganizer organizer = mock(IDisplayAreaOrganizer.class); + when(organizer.asBinder()).thenReturn(new Binder()); + + mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController + .registerOrganizer(organizer, feature); + return organizer; + } + + private void unregisterMockOrganizer(IDisplayAreaOrganizer organizer) { + mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController + .unregisterOrganizer(organizer); + } + + @Test + public void testAppearedVanished() throws RemoteException { + IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST); + verify(organizer).onDisplayAreaAppeared(any()); + + unregisterMockOrganizer(organizer); + verify(organizer).onDisplayAreaVanished(any()); + } + + @Test + public void testChanged() throws RemoteException { + IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST); + verify(organizer).onDisplayAreaAppeared(any()); + + mDisplayContent.setBounds(new Rect(0, 0, 1000, 1000)); + verify(organizer).onDisplayAreaInfoChanged(any()); + } +} diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java index b6eb9010ce90..f83128705a2a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -50,6 +50,7 @@ import android.view.test.InsetsModeSession; import androidx.test.filters.SmallTest; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -72,6 +73,11 @@ public class InsetsPolicyTest extends WindowTestsBase { sInsetsModeSession.close(); } + @Before + public void setup() { + mWm.mAnimator.ready(); + } + @Test public void testControlsForDispatch_regular() { addWindow(TYPE_STATUS_BAR, "statusBar"); @@ -194,6 +200,7 @@ public class InsetsPolicyTest extends WindowTestsBase { policy.updateBarControlTarget(mAppWindow); policy.showTransient( IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + waitUntilWindowAnimatorIdle(); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -221,6 +228,7 @@ public class InsetsPolicyTest extends WindowTestsBase { policy.updateBarControlTarget(mAppWindow); policy.showTransient( IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + waitUntilWindowAnimatorIdle(); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -249,6 +257,7 @@ public class InsetsPolicyTest extends WindowTestsBase { policy.updateBarControlTarget(mAppWindow); policy.showTransient( IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + waitUntilWindowAnimatorIdle(); InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -262,6 +271,7 @@ public class InsetsPolicyTest extends WindowTestsBase { state.setSourceVisible(ITYPE_STATUS_BAR, true); state.setSourceVisible(ITYPE_NAVIGATION_BAR, true); policy.onInsetsModified(mAppWindow, state); + waitUntilWindowAnimatorIdle(); controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java index 15417d73bd02..2251ee047d29 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.clearInvocations; @@ -53,10 +54,102 @@ public class LetterboxTest { mTransaction = spy(StubTransaction.class); } + private static final int TOP_BAR = 0x1; + private static final int BOTTOM_BAR = 0x2; + private static final int LEFT_BAR = 0x4; + private static final int RIGHT_BAR = 0x8; + @Test - public void testOverlappingWith_usesGlobalCoordinates() { - mLetterbox.layout(new Rect(0, 0, 10, 50), new Rect(0, 2, 10, 45), new Point(1000, 2000)); - assertTrue(mLetterbox.isOverlappingWith(new Rect(0, 0, 1, 1))); + public void testNotIntersectsOrFullyContains_usesGlobalCoordinates() { + final Rect outer = new Rect(0, 0, 10, 50); + final Point surfaceOrig = new Point(1000, 2000); + + final Rect topBar = new Rect(0, 0, 10, 2); + final Rect bottomBar = new Rect(0, 45, 10, 50); + final Rect leftBar = new Rect(0, 0, 2, 50); + final Rect rightBar = new Rect(8, 0, 10, 50); + + final LetterboxLayoutVerifier verifier = + new LetterboxLayoutVerifier(outer, surfaceOrig, mLetterbox); + verifier.setBarRect(topBar, bottomBar, leftBar, rightBar); + + // top + verifier.setInner(0, 2, 10, 50).verifyPositions(TOP_BAR | BOTTOM_BAR, BOTTOM_BAR); + // bottom + verifier.setInner(0, 0, 10, 45).verifyPositions(TOP_BAR | BOTTOM_BAR, TOP_BAR); + // left + verifier.setInner(2, 0, 10, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, RIGHT_BAR); + // right + verifier.setInner(0, 0, 8, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, LEFT_BAR); + // top + bottom + verifier.setInner(0, 2, 10, 45).verifyPositions(TOP_BAR | BOTTOM_BAR, 0); + // left + right + verifier.setInner(2, 0, 8, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, 0); + // top + left + verifier.setInner(2, 2, 10, 50).verifyPositions(TOP_BAR | LEFT_BAR, 0); + // top + left + right + verifier.setInner(2, 2, 8, 50).verifyPositions(TOP_BAR | LEFT_BAR | RIGHT_BAR, 0); + // left + right + bottom + verifier.setInner(2, 0, 8, 45).verifyPositions(LEFT_BAR | RIGHT_BAR | BOTTOM_BAR, 0); + // all + verifier.setInner(2, 2, 8, 45) + .verifyPositions(TOP_BAR | BOTTOM_BAR | LEFT_BAR | RIGHT_BAR, 0); + } + + private static class LetterboxLayoutVerifier { + final Rect mOuter; + final Rect mInner = new Rect(); + final Point mSurfaceOrig; + final Letterbox mLetterbox; + final Rect mTempRect = new Rect(); + + final Rect mTop = new Rect(); + final Rect mBottom = new Rect(); + final Rect mLeft = new Rect(); + final Rect mRight = new Rect(); + + LetterboxLayoutVerifier(Rect outer, Point surfaceOrig, Letterbox letterbox) { + mOuter = new Rect(outer); + mSurfaceOrig = new Point(surfaceOrig); + mLetterbox = letterbox; + } + + LetterboxLayoutVerifier setInner(int left, int top, int right, int bottom) { + mInner.set(left, top, right, bottom); + mLetterbox.layout(mOuter, mInner, mSurfaceOrig); + return this; + } + + void setBarRect(Rect top, Rect bottom, Rect left, Rect right) { + mTop.set(top); + mBottom.set(bottom); + mLeft.set(left); + mRight.set(right); + } + + void verifyPositions(int allowedPos, int noOverlapPos) { + assertEquals(mLetterbox.notIntersectsOrFullyContains(mTop), + (allowedPos & TOP_BAR) != 0); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mBottom), + (allowedPos & BOTTOM_BAR) != 0); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mLeft), + (allowedPos & LEFT_BAR) != 0); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mRight), + (allowedPos & RIGHT_BAR) != 0); + + mTempRect.set(mTop.left, mTop.top, mTop.right, mTop.bottom + 1); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect), + (noOverlapPos & TOP_BAR) != 0); + mTempRect.set(mLeft.left, mLeft.top, mLeft.right + 1, mLeft.bottom); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect), + (noOverlapPos & LEFT_BAR) != 0); + mTempRect.set(mRight.left - 1, mRight.top, mRight.right, mRight.bottom); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect), + (noOverlapPos & RIGHT_BAR) != 0); + mTempRect.set(mBottom.left, mBottom.top - 1, mBottom.right, mBottom.bottom); + assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect), + (noOverlapPos & BOTTOM_BAR) != 0); + } } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java index 67b1dacbb47b..35d1b17d5822 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java @@ -16,12 +16,23 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; +import static com.android.server.wm.ActivityStack.ActivityState.FINISHING; +import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; +import static com.android.server.wm.ActivityStack.ActivityState.PAUSING; +import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; +import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; + +import static com.google.common.truth.Truth.assertThat; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -133,5 +144,30 @@ public class RootWindowContainerTests extends WindowTestsBase { assertEquals(activity, mWm.mRoot.findActivity(activity.intent, activity.info, false /* compareIntentFilters */)); } + + @Test + public void testAllPausedActivitiesComplete() { + DisplayContent displayContent = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY); + TaskDisplayArea taskDisplayArea = displayContent.getTaskDisplayAreaAt(0); + ActivityStack stack = taskDisplayArea.getStackAt(0); + ActivityRecord activity = createActivityRecord(displayContent, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + stack.mPausingActivity = activity; + + activity.setState(PAUSING, "test PAUSING"); + assertThat(mWm.mRoot.allPausedActivitiesComplete()).isFalse(); + + activity.setState(PAUSED, "test PAUSED"); + assertThat(mWm.mRoot.allPausedActivitiesComplete()).isTrue(); + + activity.setState(STOPPED, "test STOPPED"); + assertThat(mWm.mRoot.allPausedActivitiesComplete()).isTrue(); + + activity.setState(STOPPING, "test STOPPING"); + assertThat(mWm.mRoot.allPausedActivitiesComplete()).isTrue(); + + activity.setState(FINISHING, "test FINISHING"); + assertThat(mWm.mRoot.allPausedActivitiesComplete()).isTrue(); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java index f6ed31455f18..d7462f810bb7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java @@ -40,6 +40,11 @@ class SystemServiceTestsBase { mLockRule.waitForLocked(mSystemServicesTestRule::waitUntilWindowManagerHandlersIdle); } + /** Waits until the choreographer of WindowAnimator has processed all callbacks. */ + void waitUntilWindowAnimatorIdle() { + mLockRule.waitForLocked(mSystemServicesTestRule::waitUntilWindowAnimatorIdle); + } + void cleanupWindowManagerHandlers() { mLockRule.waitForLocked(mSystemServicesTestRule::cleanupWindowManagerHandlers); } diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java index af3ec38631ae..dea9294ff75b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -429,6 +429,31 @@ public class SystemServicesTestRule implements TestRule { } } + void waitUntilWindowAnimatorIdle() { + final WindowManagerService wm = getWindowManagerService(); + if (wm == null) { + return; + } + synchronized (mCurrentMessagesProcessed) { + // Add a message to the handler queue and make sure it is fully processed before we move + // on. This makes sure all previous messages in the handler are fully processed vs. just + // popping them from the message queue. + mCurrentMessagesProcessed.set(false); + wm.mAnimator.getChoreographer().postFrameCallback(time -> { + synchronized (mCurrentMessagesProcessed) { + mCurrentMessagesProcessed.set(true); + mCurrentMessagesProcessed.notifyAll(); + } + }); + while (!mCurrentMessagesProcessed.get()) { + try { + mCurrentMessagesProcessed.wait(); + } catch (InterruptedException e) { + } + } + } + } + /** * Throws if caller doesn't hold the given lock. * @param lock the lock diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java index dcc2ff1311a5..60875de5a68b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java @@ -372,7 +372,9 @@ public class TaskRecordTests extends ActivityTestsBase { final int longSide = 1200; final int shortSide = 600; final Rect parentBounds = new Rect(0, 0, 250, 500); + final Rect parentAppBounds = new Rect(0, 0, 250, 480); parentConfig.windowConfiguration.setBounds(parentBounds); + parentConfig.windowConfiguration.setAppBounds(parentAppBounds); parentConfig.densityDpi = 400; parentConfig.screenHeightDp = (parentBounds.bottom * 160) / parentConfig.densityDpi; // 200 parentConfig.screenWidthDp = (parentBounds.right * 160) / parentConfig.densityDpi; // 100 @@ -383,21 +385,25 @@ public class TaskRecordTests extends ActivityTestsBase { assertEquals(parentConfig.screenHeightDp, inOutConfig.screenHeightDp); assertEquals(parentConfig.screenWidthDp, inOutConfig.screenWidthDp); + assertEquals(parentAppBounds, inOutConfig.windowConfiguration.getAppBounds()); assertEquals(Configuration.ORIENTATION_PORTRAIT, inOutConfig.orientation); // If bounds are overridden, config properties should be made to match. Surface hierarchy // will crop for policy. inOutConfig.setToDefaults(); - inOutConfig.windowConfiguration.getBounds().set(0, 0, shortSide, longSide); - // By default, the parent bounds should limit the existing input bounds. + final Rect largerPortraitBounds = new Rect(0, 0, shortSide, longSide); + inOutConfig.windowConfiguration.setBounds(largerPortraitBounds); task.computeConfigResourceOverrides(inOutConfig, parentConfig); - + // The override bounds are beyond the parent, the out appBounds should not be intersected + // by parent appBounds. + assertEquals(largerPortraitBounds, inOutConfig.windowConfiguration.getAppBounds()); assertEquals(longSide, inOutConfig.screenHeightDp * parentConfig.densityDpi / 160); assertEquals(shortSide, inOutConfig.screenWidthDp * parentConfig.densityDpi / 160); inOutConfig.setToDefaults(); // Landscape bounds. - inOutConfig.windowConfiguration.getBounds().set(0, 0, longSide, shortSide); + final Rect largerLandscapeBounds = new Rect(0, 0, longSide, shortSide); + inOutConfig.windowConfiguration.setBounds(largerLandscapeBounds); // Setup the display with a top stable inset. The later assertion will ensure the inset is // excluded from screenHeightDp. @@ -415,6 +421,7 @@ public class TaskRecordTests extends ActivityTestsBase { new ActivityRecord.CompatDisplayInsets(display, task); task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatIntsets); + assertEquals(largerLandscapeBounds, inOutConfig.windowConfiguration.getAppBounds()); assertEquals((shortSide - statusBarHeight) * DENSITY_DEFAULT / parentConfig.densityDpi, inOutConfig.screenHeightDp); assertEquals(longSide * DENSITY_DEFAULT / parentConfig.densityDpi, diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java index a4f1487dde1e..520ac19b89a8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java @@ -16,6 +16,9 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; @@ -251,6 +254,22 @@ public class WallpaperControllerTests extends WindowTestsBase { assertEquals(otherWindowInitialZoom, wallpaperWindow.mWallpaperZoomOut, .01f); } + /** + * Tests that the windowing mode of the wallpaper window must always be fullscreen. + */ + @Test + public void testWallpaperTokenWindowingMode() { + final DisplayContent dc = mWm.mRoot.getDefaultDisplay(); + final WallpaperWindowToken token = new WallpaperWindowToken(mWm, mock(IBinder.class), + true, dc, true /* ownerCanManageAppTokens */); + + // The wallpaper should have requested override fullscreen windowing mode, so the + // configuration (windowing mode) propagation from display won't change it. + dc.setWindowingMode(WINDOWING_MODE_FREEFORM); + assertEquals(WINDOWING_MODE_FULLSCREEN, token.getWindowingMode()); + dc.setWindowingMode(WINDOWING_MODE_UNDEFINED); + assertEquals(WINDOWING_MODE_FULLSCREEN, token.getWindowingMode()); + } private WindowState createWallpaperTargetWindow(DisplayContent dc) { final ActivityRecord homeActivity = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService) diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index f65328dcbd42..7d2e88014f45 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -81,7 +81,7 @@ import java.util.List; * Test class for {@link ITaskOrganizer} and {@link android.window.ITaskOrganizerController}. * * Build/Install/Run: - * atest WmTests:TaskOrganizerTests + * atest WmTests:WindowOrganizerTests */ @SmallTest @Presubmit @@ -264,15 +264,22 @@ public class WindowOrganizerTests extends WindowTestsBase { // newly entering the windowing mode. final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW); stack2.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - verify(organizer2).onTaskAppeared(any()); + // One each for task and task2 + verify(organizer2, times(2)).onTaskAppeared(any()); + verify(organizer2, times(0)).onTaskVanished(any()); + // One for task + verify(organizer).onTaskVanished(any()); assertTrue(stack2.isOrganized()); // Now we unregister the second one, the first one should automatically be reregistered // so we verify that it's now seeing changes. mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer2); + verify(organizer, times(3)).onTaskAppeared(any()); + verify(organizer2, times(2)).onTaskVanished(any()); stack3.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - verify(organizer, times(2)).onTaskAppeared(any()); + verify(organizer, times(4)).onTaskAppeared(any()); + verify(organizer2, times(2)).onTaskVanished(any()); assertTrue(stack3.isOrganized()); } @@ -902,12 +909,13 @@ public class WindowOrganizerTests extends WindowTestsBase { task.setHasBeenVisible(true); verify(organizer, times(1)).onTaskAppeared(any()); - task.taskOrganizerUnregistered(); + task.setTaskOrganizer(null); + verify(organizer, times(1)).onTaskVanished(any()); task.setTaskOrganizer(organizer); verify(organizer, times(2)).onTaskAppeared(any()); task.removeImmediately(); - verify(organizer).onTaskVanished(any()); + verify(organizer, times(2)).onTaskVanished(any()); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java index 07a6179c00bd..cdf8eb4faf1d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java @@ -28,9 +28,11 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.when; +import android.Manifest; import android.app.IApplicationThread; import android.content.ComponentName; import android.content.pm.ApplicationInfo; +import android.content.pm.ServiceInfo; import android.content.res.Configuration; import android.platform.test.annotations.Presubmit; @@ -200,6 +202,57 @@ public class WindowProcessControllerTests extends ActivityTestsBase { assertFalse(wpc.registeredForActivityConfigChanges()); } + @Test + public void testActivityNotOverridingImeProcessConfig() { + ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.permission = Manifest.permission.BIND_INPUT_METHOD; + // Notify WPC that this process has started an IME service. + mWpc.onServiceStarted(serviceInfo); + + final ActivityRecord activity = new ActivityBuilder(mService) + .setCreateTask(true) + .setUseProcess(mWpc) + .build(); + + mWpc.addActivityIfNeeded(activity); + // IME processes should not be registered for activity config changes. + assertFalse(mWpc.registeredForActivityConfigChanges()); + } + + @Test + public void testActivityNotOverridingAllyProcessConfig() { + ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.permission = Manifest.permission.BIND_ACCESSIBILITY_SERVICE; + // Notify WPC that this process has started an ally service. + mWpc.onServiceStarted(serviceInfo); + + final ActivityRecord activity = new ActivityBuilder(mService) + .setCreateTask(true) + .setUseProcess(mWpc) + .build(); + + mWpc.addActivityIfNeeded(activity); + // Ally processes should not be registered for activity config changes. + assertFalse(mWpc.registeredForActivityConfigChanges()); + } + + @Test + public void testActivityNotOverridingVoiceInteractionProcessConfig() { + ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.permission = Manifest.permission.BIND_VOICE_INTERACTION; + // Notify WPC that this process has started an voice interaction service. + mWpc.onServiceStarted(serviceInfo); + + final ActivityRecord activity = new ActivityBuilder(mService) + .setCreateTask(true) + .setUseProcess(mWpc) + .build(); + + mWpc.addActivityIfNeeded(activity); + // Voice interaction service processes should not be registered for activity config changes. + assertFalse(mWpc.registeredForActivityConfigChanges()); + } + private TestDisplayContent createTestDisplayContentInContainer() { return new TestDisplayContent.Builder(mService, 1000, 1500).build(); } diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index b974c567008f..0983db6d9663 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -2218,15 +2218,23 @@ public class TelecomManager { @NonNull public Intent createLaunchEmergencyDialerIntent(@Nullable String number) { ITelecomService service = getTelecomService(); - Intent result = null; if (service != null) { try { - result = service.createLaunchEmergencyDialerIntent(number); + return service.createLaunchEmergencyDialerIntent(number); } catch (RemoteException e) { Log.e(TAG, "Error createLaunchEmergencyDialerIntent", e); } + } else { + Log.w(TAG, "createLaunchEmergencyDialerIntent - Telecom service not available."); } - return result; + + // Telecom service knows the package name of the expected emergency dialer package; if it + // is not available, then fallback to not targeting a specific package. + Intent intent = new Intent(Intent.ACTION_DIAL_EMERGENCY); + if (!TextUtils.isEmpty(number) && TextUtils.isDigitsOnly(number)) { + intent.setData(Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null)); + } + return intent; } /** diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java index 151fb59b7550..ede67dd9fd61 100644 --- a/telephony/java/android/telephony/ims/ImsRcsManager.java +++ b/telephony/java/android/telephony/ims/ImsRcsManager.java @@ -49,7 +49,7 @@ import java.util.function.Consumer; * * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this manager. */ -public class ImsRcsManager implements RegistrationManager { +public class ImsRcsManager { private static final String TAG = "ImsRcsManager"; /** @@ -173,11 +173,11 @@ public class ImsRcsManager implements RegistrationManager { /** * @hide */ - @Override + // @Override add back to RegistrationManager interface once public. @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback( @NonNull @CallbackExecutor Executor executor, - @NonNull RegistrationCallback c) + @NonNull RegistrationManager.RegistrationCallback c) throws ImsException { if (c == null) { throw new IllegalArgumentException("Must include a non-null RegistrationCallback."); @@ -204,7 +204,7 @@ public class ImsRcsManager implements RegistrationManager { /** * @hide */ - @Override + // @Override add back to RegistrationManager interface once public. @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback( @NonNull RegistrationManager.RegistrationCallback c) { @@ -228,10 +228,10 @@ public class ImsRcsManager implements RegistrationManager { /** * @hide */ - @Override + // @Override add back to RegistrationManager interface once public. @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull @CallbackExecutor Executor executor, - @NonNull @ImsRegistrationState Consumer<Integer> stateCallback) { + @NonNull @RegistrationManager.ImsRegistrationState Consumer<Integer> stateCallback) { if (stateCallback == null) { throw new IllegalArgumentException("Must include a non-null stateCallback."); } @@ -260,7 +260,6 @@ public class ImsRcsManager implements RegistrationManager { /** * @hide */ - @Override @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationTransportType(@NonNull @CallbackExecutor Executor executor, @NonNull @AccessNetworkConstants.TransportType @@ -347,8 +346,7 @@ public class ImsRcsManager implements RegistrationManager { * inactive subscription, it will result in a no-op. * @param c The RCS {@link AvailabilityCallback} to be removed. * @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback) - * @throws ImsException if the IMS service is not available when calling this method - * {@link ImsRcsController#unregisterRcsAvailabilityCallback()}. + * @throws ImsException if the IMS service is not available when calling this method. * See {@link ImsException#getCode()} for more information on the error codes. * @hide */ @@ -390,8 +388,7 @@ public class ImsRcsManager implements RegistrationManager { * rather the subscription is capable of this service over IMS. * @see #isAvailable(int) * @see android.telephony.CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL - * @throws ImsException if the IMS service is not available when calling this method - * {@link ImsRcsController#isCapable(int, int)}. + * @throws ImsException if the IMS service is not available when calling this method. * See {@link ImsException#getCode()} for more information on the error codes. * @hide */ @@ -424,9 +421,8 @@ public class ImsRcsManager implements RegistrationManager { * @return true if the RCS capability is currently available for the associated subscription, * false otherwise. If the capability is available, IMS is registered and the service is * currently available over IMS. - * @see #isCapable(int) - * @throws ImsException if the IMS service is not available when calling this method - * {@link ImsRcsController#isAvailable(int, int)}. + * @see #isCapable(int, int) + * @throws ImsException if the IMS service is not available when calling this method. * See {@link ImsException#getCode()} for more information on the error codes. * @hide */ diff --git a/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java b/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java index 35a6c26ec73f..371375c0d932 100644 --- a/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java +++ b/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java @@ -77,7 +77,7 @@ public class DummyBlobData { return mRandomSeed; } - public Builder setFileSize(int fileSize) { + public Builder setFileSize(long fileSize) { mFileSize = fileSize; return this; } diff --git a/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java b/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java index 482b23f129fd..6927e86213d8 100644 --- a/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java +++ b/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java @@ -34,6 +34,9 @@ import java.io.OutputStream; public class Utils { public static final int BUFFER_SIZE_BYTES = 16 * 1024; + public static final long KB_IN_BYTES = 1000; + public static final long MB_IN_BYTES = KB_IN_BYTES * 1000; + public static void copy(InputStream in, OutputStream out, long lengthBytes) throws IOException { final byte[] buffer = new byte[BUFFER_SIZE_BYTES]; diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java index 737b7c7b9caf..b0213b0ef502 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java @@ -384,7 +384,8 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc * * For example: * To connect to an open network with a SSID prefix of "test" and a BSSID OUI of "10:03:23": - * {@code + * + * <pre>{@code * final NetworkSpecifier specifier = * new Builder() * .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX)) @@ -406,7 +407,7 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc * // etc. * }; * connectivityManager.requestNetwork(request, networkCallback); - * } + * }</pre> * * @return Instance of {@link NetworkSpecifier}. * @throws IllegalStateException on invalid params set. |