Merge "Notification removal with overflow bubbles" into rvc-dev
diff --git a/Android.bp b/Android.bp
index bd30de2..8d3b4af 100644
--- a/Android.bp
+++ b/Android.bp
@@ -708,11 +708,9 @@
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 @@
"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 270c160..bfc1367 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -97,9 +97,6 @@
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 @@
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 {
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 {
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 6af1178..b4a7cd4 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 @@
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 @@
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 1b66794..18f021c 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 80308d2..0d3f420 100644
--- a/apex/statsd/aidl/android/os/IStatsd.aidl
+++ b/apex/statsd/aidl/android/os/IStatsd.aidl
@@ -182,12 +182,6 @@
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 536b71a..4eeae57 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.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 @@
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 @@
* @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 @@
* @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 @@
* @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 @@
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 80e2d00..3f8bee9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -48759,12 +48759,8 @@
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 777cbc54..96cefe1 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -505,6 +505,11 @@
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 @@
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 @@
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.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 acd9ec3..f30ed17c 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -104,7 +104,7 @@
"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 @@
//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 @@
"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 cfc1de4..c9ccfb9 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 ba4cf11..fd86e36 100644
--- a/cmds/statsd/src/FieldValue.h
+++ b/cmds/statsd/src/FieldValue.h
@@ -27,7 +27,6 @@
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 f91c600..60e259b 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::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 @@
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::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 97512ed..ffd83ba 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -120,6 +120,11 @@
/* 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 ae7a8d0..bd9f7a5 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -118,7 +118,8 @@
}
})),
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 @@
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 @@
packageNames,
installers);
- mBootCompleteLatch.countDown(kUidMapReceivedTag);
+ mBootCompleteTrigger.markComplete(kUidMapReceivedTag);
VLOG("StatsService::informAllUidData UidData proto parsed successfully.");
return Status::ok();
}
@@ -1066,7 +1061,7 @@
ENFORCE_UID(AID_SYSTEM);
VLOG("StatsService::bootCompleted was called");
- mBootCompleteLatch.countDown(kBootCompleteTag);
+ mBootCompleteTrigger.markComplete(kBootCompleteTag);
return Status::ok();
}
@@ -1222,20 +1217,11 @@
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 79324d8..b49fa1d 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 @@
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 @@
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 @@
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 13e7ac1..b3da32fc 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -46,6 +46,7 @@
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 @@
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 @@
* 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 @@
// 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 @@
// 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 @@
* 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 @@
* 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 @@
* 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 @@
}
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 ebe9610..cfd5d14 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -252,9 +252,13 @@
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 ab0ccee..5e18aaa 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -78,11 +78,12 @@
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 @@
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 9e72a23..aa99d00 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 @@
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 @@
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 21e524a..805281c 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 eb830e1..10b1059 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -211,8 +211,8 @@
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 @@
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 @@
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 @@
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 dedcfaf..731b966 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -163,12 +163,10 @@
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 @@
// 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 a4711e8..f9a8842 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -109,10 +109,11 @@
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 cc48f99..6f84076 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -154,12 +154,14 @@
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 aa0cae2..2eb584b 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -73,18 +73,23 @@
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 @@
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 6aba13ca..91c98ea2 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -141,30 +141,25 @@
}
/**
- * 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 @@
// 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 d832ed8..d7ad27b 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -189,7 +189,7 @@
StateManager::getInstance().unregisterListener(atomId, it);
}
}
- mPullerManager->UnregisterPullUidProvider(mConfigKey);
+ mPullerManager->UnregisterPullUidProvider(mConfigKey, this);
VLOG("~MetricsManager()");
}
@@ -231,8 +231,8 @@
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::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 @@
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 @@
// 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 @@
// 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 @@
// 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 @@
}
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 1fd6572..ef03d20 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -70,6 +70,8 @@
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 e9273dc..c8dc8cc 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -69,8 +69,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 88616dd..3ab44f4 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 f9fddc8..2acffee 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/MultiConditionTrigger.cpp b/cmds/statsd/src/utils/MultiConditionTrigger.cpp
new file mode 100644
index 0000000..43a6933
--- /dev/null
+++ b/cmds/statsd/src/utils/MultiConditionTrigger.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define DEBUG false // STOPSHIP if true
+
+#include "MultiConditionTrigger.h"
+
+#include <thread>
+
+using namespace std;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+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 MultiConditionTrigger::markComplete(const string& conditionName) {
+ bool doTrigger = false;
+ {
+ lock_guard<mutex> lg(mMutex);
+ if (mCompleted) {
+ return;
+ }
+ mRemainingConditionNames.erase(conditionName);
+ mCompleted = mRemainingConditionNames.empty();
+ doTrigger = mCompleted;
+ }
+ if (doTrigger) {
+ std::thread executorThread([this] { mTrigger(); });
+ executorThread.detach();
+ }
+}
+} // 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 0000000..51f6029
--- /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.cpp b/cmds/statsd/src/utils/NamedLatch.cpp
deleted file mode 100644
index 6e77977..0000000
--- a/cmds/statsd/src/utils/NamedLatch.cpp
+++ /dev/null
@@ -1,48 +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.
- */
-#define DEBUG false // STOPSHIP if true
-
-#include "NamedLatch.h"
-
-using namespace std;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-NamedLatch::NamedLatch(const set<string>& eventNames) : mRemainingEventNames(eventNames) {
-}
-
-void NamedLatch::countDown(const string& eventName) {
- bool notify = false;
- {
- lock_guard<mutex> lg(mMutex);
- mRemainingEventNames.erase(eventName);
- notify = mRemainingEventNames.empty();
- }
- if (notify) {
- mConditionVariable.notify_all();
- }
-}
-
-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/NamedLatch.h b/cmds/statsd/src/utils/NamedLatch.h
deleted file mode 100644
index 70238370..0000000
--- 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 e52e2d0..00f336a 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -95,6 +95,7 @@
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 @@
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 @@
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 @@
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 1075fe4..a44541d 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -528,7 +528,7 @@
}));
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 d29394b..b809286 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -301,6 +301,29 @@
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 b173ee0..9117623 100644
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
@@ -89,6 +89,7 @@
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 @@
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 @@
// 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 65f8de6..8131725 100644
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -38,9 +38,9 @@
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 @@
} // 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 30f8159..8ef2519 100644
--- a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
@@ -41,10 +41,10 @@
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 @@
} // 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 @@
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 @@
*/
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 @@
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 @@
*/
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 42d0d5d..9d2ec88 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -42,6 +42,8 @@
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 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 @@
}
} // 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 @@
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 @@
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 @@
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 @@
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 @@
.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 @@
.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 @@
.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 3b4d646..f493cc4 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -41,6 +41,8 @@
namespace os {
namespace statsd {
+namespace {
+
const ConfigKey kConfigKey(0, 12345);
const int tagId = 1;
const int64_t metricId = 123;
@@ -58,10 +60,18 @@
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 @@
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 @@
}
};
+// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 69f7e3f..be410b1 100644
--- a/cmds/statsd/tests/metrics/metrics_test_helper.h
+++ b/cmds/statsd/tests/metrics/metrics_test_helper.h
@@ -44,7 +44,8 @@
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 37b9889..4d68ea2 100644
--- a/cmds/statsd/tests/statsd_test_util.h
+++ b/cmds/statsd/tests/statsd_test_util.h
@@ -42,6 +42,8 @@
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 0000000..db402a0
--- /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 de48a13..0000000
--- 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 3a26063..c33d31f 100644
--- a/cmds/uiautomator/library/Android.bp
+++ b/cmds/uiautomator/library/Android.bp
@@ -28,9 +28,6 @@
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 21b56d3..7d6ce41 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -375,7 +375,6 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
}
}
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 @@
* @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 @@
* {@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 @@
* 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 @@
// 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 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 @@
// 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 @@
}
}
+ @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 @@
+ ", 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 9d0364e..8dfce14 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -58,6 +58,7 @@
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 8edf03d..af02783 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2301,11 +2301,11 @@
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 @@
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 @@
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 @@
if (mChannelId != null) {
parcel.writeInt(1);
- parcel.writeString(mChannelId);
+ parcel.writeString8(mChannelId);
} else {
parcel.writeInt(0);
}
@@ -2811,7 +2811,7 @@
if (mShortcutId != null) {
parcel.writeInt(1);
- parcel.writeString(mShortcutId);
+ parcel.writeString8(mShortcutId);
} else {
parcel.writeInt(0);
}
@@ -8873,7 +8873,7 @@
}
mDesiredHeightResId = in.readInt();
if (in.readInt() != 0) {
- mShortcutId = in.readString();
+ mShortcutId = in.readString8();
}
}
@@ -9029,7 +9029,7 @@
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 2feb927..9f8d3c4 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -102,7 +102,7 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
* @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 @@
* @see Notification#getBubbleMetadata()
*/
public boolean canBubble() {
+ return mAllowBubbles == ALLOW_BUBBLE_ON;
+ }
+
+ /**
+ * @hide
+ */
+ public int getAllowBubbles() {
return mAllowBubbles;
}
@@ -872,7 +891,7 @@
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 @@
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 @@
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 0173731..c7a2a1e 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -20,6 +20,7 @@
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 @@
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 3a06c9d..cb416c9 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 @@
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 9c806fa..1923bf3 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -1206,7 +1206,7 @@
}
} else {
dest.writeInt(PARCEL_TYPE_STRING);
- dest.writeString(text);
+ dest.writeString8(text);
}
}
@@ -1215,7 +1215,7 @@
*/
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 494d2aea..1fb426e 100644
--- a/core/java/android/content/ContentProviderOperation.java
+++ b/core/java/android/content/ContentProviderOperation.java
@@ -91,8 +91,8 @@
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 @@
} 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 @@
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 @@
}
if (mSelection != null) {
dest.writeInt(1);
- dest.writeString(mSelection);
+ dest.writeString8(mSelection);
} else {
dest.writeInt(0);
}
@@ -591,7 +591,7 @@
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 @@
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 7c1b62f..09c6849 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5812,6 +5812,12 @@
* 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 @@
* @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 b1d6c83..def150a 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -888,8 +888,8 @@
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 void writeToParcel(Parcel dest, int flags) {
- dest.writeString(packageName);
- dest.writeString(resourceName);
+ dest.writeString8(packageName);
+ dest.writeString8(resourceName);
}
@Override
@@ -10807,12 +10807,12 @@
}
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 @@
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 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 @@
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 f25ce76..b1f8869 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1206,17 +1206,17 @@
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 @@
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 @@
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 @@
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 @@
gravity = source.readInt();
minWidth = source.readInt();
minHeight = source.readInt();
- windowLayoutAffinity = source.readString();
+ windowLayoutAffinity = source.readString8();
}
/**
@@ -1476,7 +1476,7 @@
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 b6706011..b37521b 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1704,10 +1704,10 @@
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 @@
} 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 @@
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 @@
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 @@
@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 @@
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 @@
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 @@
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 362098c..628bcd7 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -197,8 +197,8 @@
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 @@
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 144a07e..99e6d91 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -279,12 +279,8 @@
* <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 4a61938..e8fb241 100644
--- a/core/java/android/content/pm/DataLoaderManager.java
+++ b/core/java/android/content/pm/DataLoaderManager.java
@@ -41,17 +41,16 @@
* @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 @@
}
/**
- * 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 9f3ab77..89269e0 100644
--- a/core/java/android/content/pm/FeatureInfo.java
+++ b/core/java/android/content/pm/FeatureInfo.java
@@ -108,7 +108,7 @@
@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 @@
};
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 1336f72..93b3de7 100644
--- a/core/java/android/content/pm/IDataLoaderManager.aidl
+++ b/core/java/android/content/pm/IDataLoaderManager.aidl
@@ -23,8 +23,8 @@
/** @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 9819b5d..24a62c5 100644
--- a/core/java/android/content/pm/IDataLoaderStatusListener.aidl
+++ b/core/java/android/content/pm/IDataLoaderStatusListener.aidl
@@ -21,17 +21,30 @@
* @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 574a1ee..745a6c1 100644
--- a/core/java/android/content/pm/InstrumentationInfo.java
+++ b/core/java/android/content/pm/InstrumentationInfo.java
@@ -157,21 +157,21 @@
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 @@
@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 85c698f..bb56ef7 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -441,14 +441,14 @@
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 @@
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 @@
@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 @@
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 7fd5531..d41ace5 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -422,8 +422,8 @@
}
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 @@
}
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 85bafd9..8a57f82 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -6873,9 +6873,9 @@
/** @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 44def33..8212224 100644
--- a/core/java/android/content/pm/PackageParserCacheHelper.java
+++ b/core/java/android/content/pm/PackageParserCacheHelper.java
@@ -78,10 +78,19 @@
/**
* 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 @@
* 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 @@
}
}
+ @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 07d42dc..3984ade 100644
--- a/core/java/android/content/pm/ProviderInfo.java
+++ b/core/java/android/content/pm/ProviderInfo.java
@@ -145,9 +145,9 @@
@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 @@
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 5f90b6c..d3f9e24 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -244,7 +244,7 @@
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 @@
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 88f4c31..4e18979 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -1530,8 +1530,8 @@
} 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 @@
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 f7c96a3..2f67f6d 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -228,19 +228,26 @@
} catch (SQLiteCantOpenDatabaseException e) {
String message = String.format("Cannot open database '%s'", file);
- final Path path = FileSystems.getDefault().getPath(file);
- final Path dir = path.getParent();
+ try {
+ // Try to diagnose for common reasons. If something fails in here, that's fine;
+ // just swallow the exception.
- 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";
+ 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 eb6901f6..2012039 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -488,11 +488,7 @@
* 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 462110f..ad9bf07 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -65,21 +65,23 @@
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 525bbfd..1cb4fe8 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -500,7 +500,7 @@
}
static Uri readFrom(Parcel parcel) {
- return new StringUri(parcel.readString());
+ return new StringUri(parcel.readString8());
}
public int describeContents() {
@@ -509,7 +509,7 @@
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 @@
static Uri readFrom(Parcel parcel) {
return new OpaqueUri(
- parcel.readString(),
+ parcel.readString8(),
Part.readFrom(parcel),
Part.readFrom(parcel)
);
@@ -887,7 +887,7 @@
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 @@
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 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 @@
+ mCanonicalRepresentation + ")");
}
parcel.writeInt(mCanonicalRepresentation);
- parcel.writeString(canonicalValue);
+ parcel.writeString8(canonicalValue);
}
}
@@ -2060,7 +2060,7 @@
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 @@
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 f0b7b5f..93f6607 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -307,7 +307,9 @@
@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 @@
@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 @@
* 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 @@
* 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 @@
* 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 @@
* @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 @@
*/
@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 @@
*
* @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 251995a..321dc9e 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.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 @@
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 @@
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");
+ 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.openStorage(incrementalPath);
- } else {
- mDefaultDir = getTempDir();
- if (mDefaultDir == null) {
- throw new IOException("Failed to create storage: tempDir is empty");
- }
- 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 @@
* 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 35518db..916edfa 100644
--- a/core/java/android/os/incremental/IncrementalManager.java
+++ b/core/java/android/os/incremental/IncrementalManager.java
@@ -32,8 +32,12 @@
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 @@
}
/**
- * 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 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);
}
- linkFiles(apkStorage, beforeCodeFile, "", linkedApkStorage, afterCodePathName);
- apkStorage.unBind(beforeCodePath);
+ try {
+ final String afterCodePathName = afterCodeFile.getName();
+ linkFiles(apkStorage, beforeCodeAbsolute, "", linkedApkStorage, afterCodePathName);
+ apkStorage.unBind(beforeCodeAbsolute.toString());
+ } catch (Exception e) {
+ linkedApkStorage.unBind(targetStorageDir);
+ throw e;
+ }
}
/**
@@ -252,22 +235,27 @@
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()) {
- sourceStorage.makeLink(
- sourceEntryRelativePath, targetStorage, targetEntryRelativePath);
- } else if (entry.isDirectory()) {
- linkFiles(sourceStorage, entry, sourceEntryRelativePath, targetStorage,
- targetEntryRelativePath);
+ 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(
+ 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 fe340c4..ac1998a 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8607,6 +8607,16 @@
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 df4ead1..28639b3 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -748,7 +748,7 @@
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 @@
} 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 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 f37e423..d6d99f8 100644
--- a/core/java/android/text/style/DynamicDrawableSpan.java
+++ b/core/java/android/text/style/DynamicDrawableSpan.java
@@ -166,7 +166,7 @@
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 a723839..2dcfd89 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -69,6 +69,13 @@
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 @@
} 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 @@
* 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 fba6a55..94591eaf 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -145,6 +145,7 @@
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 4980b33..6646c31 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -3437,6 +3437,7 @@
* @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 9f03d95..16e87f8 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -5863,6 +5863,7 @@
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 8d9ae58..00526d9 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -821,6 +821,7 @@
// 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
old mode 100644
new mode 100755
index 8595fec..6425cf1
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -1005,6 +1005,7 @@
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 e9e0c14..baaf2a7 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1033,6 +1033,7 @@
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 7f6c0d2..7016c5c 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1213,7 +1213,7 @@
BitmapReflectionAction(Parcel in) {
viewId = in.readInt();
- methodName = in.readString();
+ methodName = in.readString8();
bitmapId = in.readInt();
bitmap = mBitmapCache.getBitmapForId(bitmapId);
}
@@ -1221,7 +1221,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(viewId);
- dest.writeString(methodName);
+ dest.writeString8(methodName);
dest.writeInt(bitmapId);
}
@@ -1282,7 +1282,7 @@
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 @@
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 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 @@
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
old mode 100644
new mode 100755
index 15959c2..6ef570c
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -1076,7 +1076,8 @@
// 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 217693e..61c77bc 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -420,6 +420,7 @@
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 e933f18a..ec07574 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8359,6 +8359,7 @@
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 @@
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 0000000..b745017
--- /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 0000000..0d35bca
--- /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 6ae70b7..f3ef5a0 100644
--- a/core/java/android/window/DisplayAreaOrganizer.java
+++ b/core/java/android/window/DisplayAreaOrganizer.java
@@ -52,21 +52,42 @@
}
}
- 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 onDisplayAreaVanished(@NonNull WindowContainerToken displayArea) {}
+ public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo) {}
+ 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 WindowContainerToken displayArea) {
- DisplayAreaOrganizer.this.onDisplayAreaVanished(displayArea);
+ public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) {
+ DisplayAreaOrganizer.this.onDisplayAreaVanished(displayAreaInfo);
+ }
+
+ @Override
+ 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 9c72e60..39a9235 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 fc6fbef..41b9d02 100644
--- a/core/java/android/window/IDisplayAreaOrganizerController.aidl
+++ b/core/java/android/window/IDisplayAreaOrganizerController.aidl
@@ -23,4 +23,9 @@
/** 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 b1e356d..bcb32fb 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -437,6 +437,9 @@
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 @@
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 970bab9..b671fa7 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2721,11 +2721,12 @@
}
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 @@
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 @@
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 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 @@
}
}
+ /**
+ * 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 @@
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 @@
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 1bc982c..00faa3b 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -146,6 +146,7 @@
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 @@
}
@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 @@
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 @@
}
setupViewVisibilities();
maybeLogProfileChange();
+ onProfileTabSelected();
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.RESOLVER_SWITCH_TABS)
.setInt(viewPager.getCurrentItem())
@@ -1628,6 +1641,12 @@
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 @@
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 ad31d8b..885d1bb 100644
--- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
@@ -213,6 +213,12 @@
/* 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 43bd4a6..6432475 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -6093,7 +6093,8 @@
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 31527e8..fb2ecf3 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -1084,6 +1084,7 @@
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 @@
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 @@
static class SavedState extends BaseSavedState {
boolean open;
+ private int mCollapsibleHeightReserved;
SavedState(Parcelable superState) {
super(superState);
@@ -1150,12 +1153,14 @@
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 b51d4f5..4cb2e97 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -301,6 +301,8 @@
}
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 @@
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 483b455..e7a2fb4 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -273,7 +273,28 @@
}
}
-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 @@
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 @@
// @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 @@
// @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 21985f0b..3a5720fd 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 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 @@
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 3e007e4..997829e 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2523,16 +2523,10 @@
// 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 6804d3f..30d365c 100644
--- a/core/proto/android/app/tvsettings_enums.proto
+++ b/core/proto/android/app/tvsettings_enums.proto
@@ -298,6 +298,12 @@
// 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 075aa97..fe8a0f1 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -397,6 +397,13 @@
}
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 @@
// 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 0000000..5118ad5
--- /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 61b9b25..b17d12c 100644
--- a/core/proto/android/stats/dnsresolver/dns_resolver.proto
+++ b/core/proto/android/stats/dnsresolver/dns_resolver.proto
@@ -211,7 +211,7 @@
// 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
deleted file mode 100644
index 60dcf2a..0000000
--- a/core/res/res/drawable-hdpi/ic_user_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_user_secure.png b/core/res/res/drawable-mdpi/ic_user_secure.png
deleted file mode 100644
index 0dea77a..0000000
--- a/core/res/res/drawable-mdpi/ic_user_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_user_secure.png b/core/res/res/drawable-xhdpi/ic_user_secure.png
deleted file mode 100644
index a6ef51a..0000000
--- a/core/res/res/drawable-xhdpi/ic_user_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_user_secure.png b/core/res/res/drawable-xxhdpi/ic_user_secure.png
deleted file mode 100644
index e6154e5..0000000
--- a/core/res/res/drawable-xxhdpi/ic_user_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/ic_user_secure.png b/core/res/res/drawable-xxxhdpi/ic_user_secure.png
deleted file mode 100644
index 9a3959b..0000000
--- a/core/res/res/drawable-xxxhdpi/ic_user_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_user_secure.xml b/core/res/res/drawable/ic_user_secure.xml
new file mode 100644
index 0000000..9e6355c
--- /dev/null
+++ b/core/res/res/drawable/ic_user_secure.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.
+-->
+<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 25615d2..fe11769 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 b754e0c..76ecefc 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" />
+ <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 d8ab37f..9d152aa 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 eb18af6..af6e15f 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 77692cf..7a2639d 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 3fa7a7f..c998ff0 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 9f9d293..1bb162d 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 6ab96fd..eb2f01b 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 3fc07e9..9e73d42 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 937f899..ee6bdd9 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 d8960b8..ed77cdd 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 9fee46f..7149a83 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 fe4861a..2c135fb 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 02a047c..95d71f6 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 9687e6c..05b5e52 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 3bde4cb..6c19031 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 87b0f79..b923564 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 3de520e..518aa60 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 34117aa..f004b8a 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 5b56437..474c803 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 77c0f0c..2469327 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 2b3b555..38f9c6a 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 f540953..86facd4 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 714bb7c..c7cdd13 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 191bf18..07e14fef 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 a52d564..ee4741c 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 f6cb875..b446c27 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 a88dd28..1795315 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 42e1316..441a2ee 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 3d6791f..b6ff57b 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 85926d2..6c017e8 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 bddd1ae..f656326 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 3c57bc5..87b670a 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 d68f6cf..17924e4 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 d8f5bb8..9c85285 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 96e7060..d2773a2 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 81a324e..3b48199 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 07342c0..64002ef 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 0a56fb6..ac691ae 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 81ede7d..558b5ef 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 60b91f7..5ff7a69 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 6efae06..2b04156 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 aad9a69..c80e3ac 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 9eb7aac..f7e23a8 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 5b56aa7c3..3c76caf 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 ac29610..f996343 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 cc66d3b..8a4148a 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 cd7d9db..7c6f3e7 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 a398bca..9f75ce2 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 20461de..17989bf 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 40e9e12..57e167b 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 e535311..4735b57 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 b052be4..f219bd3 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 a839a42..1354a37 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 fb7a14c..b5d2e99 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 a839a42..1354a37 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 4867642..73c3e42 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 6ecf5811..7b2e882 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 eaa93bf..3a8639e 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 e552358..dee51d5 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 7d7b0e9..1511c18 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 085a0eb..6bf4306 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 55c1fef..9f0dfb1 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 4e9c1fa..2e6a848 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 f26ce70..1b5d671 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 71072f8..2a03f36 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 01a60b0..f848950 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 ad11d6b..ff5557d 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 fbcd155..5de4525 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 91c48d5..b10d193 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 76dad91..f42d156 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 d066793..e7574b1 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 5d99692..3b2de1c 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 dda38c3..dd88759 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 002312c..4d790c46 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 fa59e3c..e18b51e 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 054f4b1..a9af563 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 1a98553..ab79d2d 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 05c00ce..5f93506d 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 0000000..daa90c2
--- /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 46873b9..dcb3e2f 100644
--- a/core/tests/coretests/src/android/os/ParcelTest.java
+++ b/core/tests/coretests/src/android/os/ParcelTest.java
@@ -87,4 +87,27 @@
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 1db2f63..b351b3d 100644
--- a/identity/java/android/security/identity/IdentityCredential.java
+++ b/identity/java/android/security/identity/IdentityCredential.java
@@ -95,9 +95,7 @@
/**
* 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 @@
* 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 @@
* 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 @@
* ? "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 @@
* 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 @@
* 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 @@
* @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 @@
* 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 @@
* <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 a1dfc77..4f834d2 100644
--- a/identity/java/android/security/identity/IdentityCredentialStore.java
+++ b/identity/java/android/security/identity/IdentityCredentialStore.java
@@ -78,17 +78,21 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 13552d6..37de2c4 100644
--- a/identity/java/android/security/identity/ResultData.java
+++ b/identity/java/android/security/identity/ResultData.java
@@ -34,23 +34,23 @@
/** 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 @@
*
* 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 @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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 e2a389b..c7aa328 100644
--- a/identity/java/android/security/identity/WritableIdentityCredential.java
+++ b/identity/java/android/security/identity/WritableIdentityCredential.java
@@ -41,15 +41,16 @@
* <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 3e1f72d..8ea6883 100755
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2713,6 +2713,32 @@
}
/**
+ * @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 c11762b..373f6e1 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -214,6 +214,175 @@
}
}
+ /**
+ * @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 540955f..f6f482d 100644
--- a/media/java/android/media/MediaMetrics.java
+++ b/media/java/android/media/MediaMetrics.java
@@ -38,6 +38,117 @@
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 0ea9624..2c65cc4 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -35,7 +35,6 @@
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 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 @@
* 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 @@
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 @@
}
}
+ @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 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 @@
}
}
- 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 @@
return;
}
- matchingController.releaseInternal(/* shouldReleaseSession= */ false);
+ matchingController.releaseInternal(
+ /* shouldReleaseSession= */ false, /* shouldNotifyStop= */ true);
}
void onGetControllerHintsForCreatingSessionOnHandler(long uniqueRequestId,
@@ -814,8 +819,9 @@
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 @@
/**
* 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 @@
*/
// 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 @@
}
}
- 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 @@
}
@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 @@
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 629cf154..608e29a 100644
--- a/media/java/android/media/RoutingSessionInfo.java
+++ b/media/java/android/media/RoutingSessionInfo.java
@@ -310,19 +310,19 @@
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 0000000..e5d0370
--- /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 d331126..50af60a 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -353,13 +353,16 @@
@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 @@
}
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 @@
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 @@
@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 @@
+ "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 @@
* @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 @@
* @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 @@
*/
@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 @@
*/
@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 @@
*/
@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 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 @@
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 @@
}
mLnb = newLnb;
mLnb.setCallback(executor, cb, this);
+ setLnb(mLnb);
}
return mLnb;
}
@@ -944,7 +976,9 @@
*/
@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 @@
@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 @@
@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 @@
@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 e6962a1..aba74e5 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -46,6 +46,7 @@
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForNative;
+import com.android.internal.annotations.VisibleForTesting;
import dalvik.system.CloseGuard;
@@ -408,7 +409,8 @@
}
@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 @@
}
@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 @@
}
@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 @@
}
@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 ba75263..88c32a3 100644
--- a/media/java/android/mtp/MtpStorage.java
+++ b/media/java/android/mtp/MtpStorage.java
@@ -36,7 +36,7 @@
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 614fe73..ab311c0e 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -1130,7 +1130,7 @@
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 @@
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 @@
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 @@
{ "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 750b146..3da78ac 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -191,6 +191,8 @@
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 0000000..e69de29
--- /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 0000000..e2e8ff4
--- /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 71e74cf..d0916b5 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 f016dbf..de5a150 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 e2e9a33..1418bf8 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 1c5d37f..a040e80 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 327610a..d386ce3 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 f016dbf..de5a150 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 ce0d31c..3389a7a 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 a71567c..9634950 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 8eba6dc..8a54c3b 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 1e971b4..733349c 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 0000000..320df58
--- /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 1caf65a..98dd49b 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 e0a34fd..3f01a3a 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 8c58c54..1b26c37 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 c638304..dda69ec 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 db072df..1c56256 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 e0a34fd..4b096d6 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 1d743f9..a78bff1 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 5548252c..d2fdf36 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 141a795..90bd0ac 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 bfb27c23c..e5695f7 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 d851133..fcbb0fd 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 617710a..a87eb87 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 617710a..a87eb87 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 617710a..a87eb87 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 617710a..a87eb87 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 fec49f2..6821c3e 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 e66891f..060c812 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 a9d1b5f..c3cc86a 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 e7f98c2..1bf7ce5 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 b8dd6fd..1786381 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 06e401b..0bd79ba 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 3476db7..7aa5a54 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 c1ee701..22b4409 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 3bfdef1..b28c620 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 c8d6622..d2178ab 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 e966acc..3913f27 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 51b1943..befdbe9 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 3613da7..bd1e6dc 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 3850f70..048d44a 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 c702bdb6..d6d7cfb 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 3ca6f30..2b205b8 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 54a4e1c..707f2f4 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 0000000..93f2401
--- /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 ab20a20..85bd0bf 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 94e25ea..0e67f2a 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 0000000..94a192e
--- /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 e865fc7..47b659f 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 0d425bb..50e1721 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 695ee3f..75b16a8 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 0000000..e9da09d
--- /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 0000000..1721377
--- /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 80c63d9..d504c12 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 f63023c..8a0be70 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 fccd94cd..63cea06 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 b30e274..f7934d1 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 e04ff9d..bae5c64 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 0d153fa..868a060 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 a1817ed..231b41f 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 b84e4ed..9141cfc 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 0000000..b17c8b4
--- /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 1739589..5ba7ce4 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 0000000..4d1a6ac
--- /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 cc6fbe5..8184c2c 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 1b083d3..35d735b 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 d6ba008..7b0ee14 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 ded1624..fab603d 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 bb0f866..adf83a3 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 6b6fdc9..69ee939 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 08baac3..061d4ed 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 086de1e..619cf29 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 8c4b5ef..b386591 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 8ea6fd2..2096967 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 bd6e25f..af3f5b8 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 fbeacf6..1aa0868 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 0000000..9f76f77
--- /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 bc85331..bfa586f 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 e291aa2..57ac7dc 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 a0a38fa..5e0af6d 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 5eaae11..7949329 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 4b465f2..f61ddf4 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 0000000..50342a3
--- /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 796c649..e0f8378 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 e4f2455..ce1826bc 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 4f2f9ca..431fd62 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 4ba404d..24efc22 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 4ba404d..e1356ca 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 432328b..94381b7 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 a5445c5..eb1d9d0 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 59fa9d0..58e4b9a 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -18,19 +18,23 @@
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.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 @@
@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 4ea48ba..f066bf5 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.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.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.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 @@
groupManager, configurationController);
}
- @Binds
- abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone);
-
@Singleton
@Provides
@Named(LEAK_REPORT_EMAIL_NAME)
@@ -97,6 +94,16 @@
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 @@
@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
similarity index 96%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/bluetooth/CarBatteryController.java
index 4e0fd4a..9b5e2712 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 @@
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 @@
mContext.registerReceiver(this, filter);
}
+ /** Stops listening for bluetooth broadcast messages. */
public void stopListening() {
mContext.unregisterReceiver(this);
}
@@ -279,8 +282,10 @@
* 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
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/bluetooth/ConnectedDeviceSignalController.java
index 3288927..4642868 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 @@
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 @@
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
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/AnimatedTemperatureView.java
rename to packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java
index 908aaad..a729431 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.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
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/hvac/HvacController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java
index fd9c488..af8ddb6 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
similarity index 96%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureBackgroundAnimator.java
rename to packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureBackgroundAnimator.java
index 3c6d623..a4c4573 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
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureColorStore.java
rename to packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureColorStore.java
index a40ffaf..9a7b0b9 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
similarity index 95%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureTextAnimator.java
rename to packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextAnimator.java
index 8ee5ef6..74d9704 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
similarity index 95%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/hvac/TemperatureTextView.java
rename to packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java
index ad4fcd9..521a665 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
similarity index 93%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/hvac/TemperatureView.java
rename to packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java
index 963f318..6b903fa 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 4fde309..b5f648b 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.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.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 db0f5d8..5a35c48 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
similarity index 95%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/AssitantButton.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/AssitantButton.java
index 98cc00e..69ec78e 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
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java
index c36aaa0..eedcfa5 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
similarity index 94%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateListener.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java
index 9da4121..1361798 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
similarity index 96%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
index 2c2aec2..2b5cab7 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.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 @@
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 @@
ButtonSelectionStateListener buttonSelectionStateListener,
@Main Handler mainHandler,
Lazy<KeyguardStateController> keyguardStateControllerLazy,
- Lazy<NavigationBarController> navigationBarControllerLazy,
ButtonSelectionStateController buttonSelectionStateController,
PhoneStatusBarPolicy iconPolicy,
StatusBarIconController iconController
@@ -139,7 +136,6 @@
mButtonSelectionStateListener = buttonSelectionStateListener;
mMainHandler = mainHandler;
mKeyguardStateControllerLazy = keyguardStateControllerLazy;
- mNavigationBarControllerLazy = navigationBarControllerLazy;
mButtonSelectionStateController = buttonSelectionStateController;
mIconPolicy = iconPolicy;
mIconController = iconController;
@@ -315,11 +311,6 @@
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
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
index 37a8225..55c1153 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.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
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
index 5b99f53..46a720b 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 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
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationButton.java
index b4d4785..5f4ac2d 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
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/NavigationBarViewFactory.java
index e47c5d1..3b7b48a 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 d8a894c..a17a0e9 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.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 9d71797..24a84d9 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.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
similarity index 95%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java
rename to packages/CarSystemUI/src/com/android/systemui/car/notification/PowerManagerHelper.java
index 615a7bae..92a11d8 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
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/sideloaded/car/CarSideLoadedAppDetector.java
rename to packages/CarSystemUI/src/com/android/systemui/car/sideloaded/CarSideLoadedAppDetector.java
index c0dbb58..f145b14 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
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
rename to packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBar.java
index ec1dabc..b6eb015 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.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.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
similarity index 96%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
rename to packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarKeyguardViewManager.java
index e1c051f..96a998a 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.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
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
rename to packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarModule.java
index f72ab25..dc2eb04 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.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 45ceb6d..10b2b97 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 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 149531f..346c38c 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
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/voicerecognition/car/ConnectedDeviceVoiceRecognitionNotifier.java
rename to packages/CarSystemUI/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifier.java
index 2f79f96..c054d20 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
similarity index 88%
rename from packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java
rename to packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java
index 5a34436..98d24b1 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
similarity index 93%
rename from packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
rename to packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java
index 873d7d7..1281884 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 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 @@
*/
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 @@
// 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 @@
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 @@
private void showH(int reason) {
- if (D.BUG) {
+ if (DEBUG) {
Log.d(TAG, "showH r=" + Events.DISMISS_REASONS[reason]);
}
@@ -323,7 +341,7 @@
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 @@
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 @@
}
private void dismissH(int reason) {
- if (D.BUG) {
+ if (DEBUG) {
Log.d(TAG, "dismissH r=" + Events.DISMISS_REASONS[reason]);
}
@@ -365,7 +383,7 @@
.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 @@
/* 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 @@
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 @@
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 @@
/* showSupplementalIconDivider= */ false);
}
- volumeItem.carVolumeItem = carVolumeItem;
- volumeItem.progress = seekbarProgressValue;
+ volumeItem.mCarVolumeItem = carVolumeItem;
+ volumeItem.mProgress = seekbarProgressValue;
return carVolumeItem;
}
@@ -490,13 +508,12 @@
* 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 @@
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
similarity index 96%
rename from packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItem.java
rename to packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItem.java
index b83740f..1e7e534 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 @@
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
similarity index 94%
rename from packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItemAdapter.java
rename to packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItemAdapter.java
index 5c1f817..7f336b5 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 0000000..2bdb85f
--- /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
similarity index 99%
rename from packages/CarSystemUI/src/com/android/systemui/window/OverlayPanelViewController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
index 58022f1..90892d5 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
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/window/OverlayViewController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java
index 15ef0be..87f2020 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
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/window/OverlayViewGlobalStateController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java
index 5fe03f1..290505f 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
similarity index 96%
rename from packages/CarSystemUI/src/com/android/systemui/window/OverlayViewMediator.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java
index 7c34fb4..ac574ed 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
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/window/OverlayWindowModule.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java
index 6b4f3e3..c46b287 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
similarity index 99%
rename from packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java
index 5df5d6e..bcd96f6 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
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowManager.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java
index af0f17d..3f88422 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
similarity index 97%
rename from packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/hvac/HvacControllerTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java
index a71d1db..7996170 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 d4cf6cc..d40b1af 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.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
similarity index 97%
rename from packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/ButtonSelectionStateControllerTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java
index f94dd82..893057e 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
similarity index 98%
rename from packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarControllerTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java
index bbcd0d4..911f624 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 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
similarity index 97%
rename from packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
index 6da34d4..6620e9d 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.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 @@
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
- private NavigationBarController mNavigationBarController;
- @Mock
private ButtonSelectionStateController mButtonSelectionStateController;
@Mock
private PhoneStatusBarPolicy mIconPolicy;
@@ -88,8 +85,8 @@
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
similarity index 98%
rename from packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarViewTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java
index 9e2131c..19e394f 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
similarity index 98%
rename from packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationButtonTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java
index 96d567d..11f2fa4 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
similarity index 99%
rename from packages/CarSystemUI/tests/src/com/android/systemui/sideloaded/car/CarSideLoadedAppDetectorTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/CarSideLoadedAppDetectorTest.java
index aebb0e0..80f3d1ee 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
similarity index 93%
rename from packages/CarSystemUI/tests/src/com/android/systemui/voicerecognition/car/ConnectedDeviceVoiceRecognitionNotifierTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java
index 38b47d0..eca51e3 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
similarity index 99%
rename from packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayPanelViewControllerTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java
index 04f2d06..70f1d25 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
similarity index 98%
rename from packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewControllerTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java
index 3313261..c24a3b5 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
similarity index 98%
rename from packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewGlobalStateControllerTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java
index a96b906..25dd4f5 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 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
index 7d9f8e3..7bdb2a8 100644
--- a/packages/CtsShim/apk/arm/CtsShim.apk
+++ b/packages/CtsShim/apk/arm/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/arm/CtsShimPriv.apk b/packages/CtsShim/apk/arm/CtsShimPriv.apk
index dcccada..8efd3b2 100644
--- a/packages/CtsShim/apk/arm/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/arm/CtsShimPriv.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShim.apk b/packages/CtsShim/apk/x86/CtsShim.apk
index 7d9f8e3..7bdb2a8 100644
--- a/packages/CtsShim/apk/x86/CtsShim.apk
+++ b/packages/CtsShim/apk/x86/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShimPriv.apk b/packages/CtsShim/apk/x86/CtsShimPriv.apk
index 3501fa4..eed29d1 100644
--- a/packages/CtsShim/apk/x86/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/x86/CtsShimPriv.apk
Binary files differ
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 617305c..f1ec606 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -433,7 +433,7 @@
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 90526db..1eef0b7 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 96c4a65..f8dcb3a 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 cdbdc9a..aee5061 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 4ec5156..40eb00b 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 a93b422..e9d314b 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 32ed895..713c7cd 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 0e5ae09..57456d9 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 babf00b..decb3da 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 2495fd5..0a9d260 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 32ff89f..ffa55af 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 26db499..504cc5e 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 199fad5..2f929f7 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 3b2b2a8..7838a0c 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 224e6ff..f617a93 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 a932bce..f6d6d77 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 a932bce..f6d6d77 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 a932bce..f6d6d77 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 a932bce..f6d6d77 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 6295fe6..b0424e2 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 11726ae..dcfee98 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 d32f6a7..e7a8475 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 7332010..f42111d 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 321d6df..85260fe 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 1687e54..6afa889 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 d75cc19..9e1fa76 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 fdace21..146fbe9 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 425a22b..c2a8d49 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 bbc4e18..2a6bcfc 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 94d4c92..4be85c7 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 9dcdf0e..115fef8 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 15f008b..a223b4d 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 b1639b5..8d40abc 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 3d18da0..3f11da3 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 17c6fec..d925df3 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 e4883be..3f38597 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 da17dd7..53f82eb 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 ef41da3..2f91ea6 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 4e28c5b..21ebced 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 a9f2a1b..f33a094 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 0e566c1..aa52052 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 4e873be..aece31f 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 8530440..9dbeb45 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 fc63435..66c5c4f 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 5d4efe2..f5816b3 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 e2ccc3a..4772124 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 64368b7..9b9da06 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 e285abd..c272c5a 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 7ab2bbb..f61c44c 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 7ed1078..3380645 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 09a558d..294ab274 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 27b1a2c..7525a0f 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 cc883ab..3f38771 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 6094224..200e0ec 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 c566dc2..176a8b7 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 b3ee2e3..a38a3ea 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 138c72d..4ba370b 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 023b326..d371c52 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 0b239a5..9124958 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 a008504..6082965 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 0b239a5..9124958 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 b0d78cd..fa43c13 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 a375bdb..bb06071 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 d22a643..9595bd1 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 c6ea18b..ea8cf73 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 1c83a7f..893b207 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 2a50f58..4debe74 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 45dbd36..e47969c 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 efb4ddc..c21e624 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 a0254cb..66846fa 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 8d251ac..4494d1a 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 c51c042..ff958ea 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 7ab86e8..844a329 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 d3af398..412be0f 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 039df1a..26f94bf1 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 60aa1a9..6f6b3fc 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 d1caa711..215cb4c 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 1d78d33..e118ec0 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 5c65dff..9edcff2 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 3720581..b6ad4fd 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 9337b59..04b5cb6 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 a552446..7e84918 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 1007d83..7baaf49 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 deccde5..a210e90 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 @@
}
});
- // 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 342d127a..4b779ac 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 @@
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 @@
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 @@
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 736e995..c04a1ba 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 @@
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 b413e8e..76746e5 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 @@
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 8a7b913..a5dce6d 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 @@
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 d3d04e5..74eee63 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 @@
}
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 @@
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 be3c598..f0dfd21 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 34b603f..d1ce10e 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 6da96d1..835e54e 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">
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textSize="@dimen/controls_title_size"
+ android:textAlignment="center" />
- <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" />
-
- </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 1c4ec64..66f57fd 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 d506e7e..db109fe 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 8342ccd..1008d2b 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 aacd994..7e2ec10 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 2410ca6..0ada0dc 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 9ea949e..99cc25d 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 8e14f9c..bbb51e1 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 da7f61b..cef3cce 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 c19fde3..a4aea02 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 5c21653..9a505cb 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 6f12900..ca02964 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 29b435f..4692c0b 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 3a859cb..3697151 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 a09e9db..15fff73 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 e134c8e..f996cb9 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 de89269..31837ed 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 cc3ee45..b3142e9 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 69109a7..b4c380b 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 fdcad12..c719ea0 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 69109a7..b4c380b 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 69109a7..b4c380b 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 2ad3809..2e5f1e7 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 d18b88c..879fc35 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 90787d0..7e3fdc7 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 a2b687e..fa6447b 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 590cfaf..1d90e92 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 a6e12bc..5860af6 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 e15547a..0420453 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 7372031..da44d88 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 22830bc..0899e09 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 1f2b827..2e910c7 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 72120ce..715c40b 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 d0e6003..af45c68 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 cbffb1f..7bcb22e 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 480228b..b5e6474 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 0bf29ed..f2ec4b9 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 ddcbcab..f9126db 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 b9c8c05..e8e5b7a 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 5f815d1..c4b167b 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 fe94f6a..894bb03 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 94e80a6..74e996b 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 dd3c267..d1b3334 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 d88e79d..82f7753 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 fb430a6..aa1d776 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 f5569bb..6fb7a1f 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 7c9f074..f8e6b1f 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 1c8d529..ae6c50a 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 0e6f6e5..880ecea 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 a4770f1..7374acd 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 c1fe506..2ace267 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 ed2ec3e..67392bb 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 99488b2..44a2aa1 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 6cba12e..0f17270 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 e33d8d7..926b636 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 6f60bf0..efd2c85 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 dab402e..e4a07fb 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 7751e6fa..5ee07ae 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 a7330f0..ec7efdb 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 93aa270..2d51011 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 98247a8..dd730d4 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 134c119..cde084f 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 1c99ea3..4e6247a 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 81dff41..e577fd2 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 cd1cd2d..0544c50 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 b0c815d..9a7f817 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 cd1cd2d..0544c50 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 2ac41df..dc5c682 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 580cd42..00e8e60 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 77f6ce6..1fde1e2 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 19f4f3d..7504f15 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 e30e042..b427601 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 25bc60d..ae60891 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 d80d774..c32626c 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 6218b7b..6ef1dfd 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 2cba96a..01cd04a 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 6dab250..a0e31d2 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 e365171..e747009 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 3965871..bde22a5 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 ceb9ae1..cafaaac 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 d8c822f..c9d5335 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 4c80dbb..00e9d58 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 6b2ef87..6cc8dd3 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 8fb32e6..43099f4 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 e3e525e..c0996af8 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 9900c95..fba35b2 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 7002a87..3c06542 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 170c2f9..de15aff 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 127d62d..e979342 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 4482cda..2e217a5 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 179f8b8..bad18cf 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 4ed819e..26ae790 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 4b50378..4d7eb75 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.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 @@
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 @@
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 0002e86..35406c7 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
@@ -128,15 +128,29 @@
*/
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, 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, @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) {
- mAnimatingCollapse = false;
- mAnimatingExpand = true;
- mAfterExpand = after;
-
- startOrUpdatePathAnimation(true /* expanding */);
+ expandFromStack(after, null /* leadBubbleEndAction */);
}
/** Animate collapsing the bubbles back to their stacked position. */
@@ -237,11 +251,17 @@
? (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 b1bbafc..a7d1be1 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 @@
* 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 7e8fec7..e84f439 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.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 @@
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 @@
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 @@
}
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 79a5b0a..bc97c10 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 @@
* 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 5626a5d..8e88756 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 @@
private var userChanging: Boolean = true
- private var loadCanceller: Runnable? = null
-
private var seedingInProgress = false
private val seedingCallbacks = mutableListOf<Consumer<Boolean>>()
@@ -276,28 +274,29 @@
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 @@
}
override fun error(message: String) {
- loadCanceller = null
executor.execute {
val controls = Favorites.getStructuresForComponent(componentName)
.flatMap { st ->
@@ -348,6 +346,7 @@
}
}
}
+ )
)
}
@@ -432,12 +431,6 @@
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 273e47c..640c90d 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.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 @@
*/
class ControlsEditingActivity @Inject constructor(
private val controller: ControlsControllerImpl,
- broadcastDispatcher: BroadcastDispatcher
+ broadcastDispatcher: BroadcastDispatcher,
+ private val globalActionsComponent: GlobalActionsComponent
) : LifecycleActivity() {
companion object {
@@ -86,12 +88,20 @@
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 @@
}
}
+ 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 4a34705..9a2ccb5 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.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.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.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 @@
@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 @@
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 @@
}
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 @@
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 @@
ControlsAnimations.enterAnimation(pageIndicator).start()
ControlsAnimations.enterAnimation(structurePager).start()
}
- })
+ }, Consumer { runnable -> cancelLoadRunnable = runnable })
}
}
@@ -275,8 +261,6 @@
}
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 @@
}
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 @@
}
}
+ val rootView = requireViewById<ViewGroup>(R.id.controls_management_root)
doneButton = requireViewById<Button>(R.id.done).apply {
isEnabled = false
setOnClickListener {
@@ -309,7 +293,16 @@
StructureInfo(component!!, it.structureName, favoritesForStorage)
)
}
- finishAffinity()
+
+ ControlsAnimations.exitAnimation(
+ rootView,
+ object : Runnable {
+ override fun run() {
+ finish()
+ }
+ }
+ ).start()
+ globalActionsComponent.handleShowGlobalActionsMenu()
}
}
}
@@ -319,15 +312,39 @@
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 59a8b32..0044854 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.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 @@
}
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 @@
}
})
}
+ }
- 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 b3c6cab..0af29be 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 @@
}
/**
- * 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 61a323d0..5be2f22 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 @@
val layout: ViewGroup,
val controlsController: ControlsController,
val uiExecutor: DelayableExecutor,
- val bgExecutor: DelayableExecutor,
- val usePanels: Boolean
+ val bgExecutor: DelayableExecutor
) {
companion object {
@@ -159,8 +158,7 @@
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 @@
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 cfd8df0..bf0f1c8 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.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 @@
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 @@
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 @@
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 15c41a2..65ed967 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.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 @@
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 @@
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 @@
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 @@
// 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 @@
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 88f96a8..8c572fe 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 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.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 @@
@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 2e9ce12..90cd13f 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.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 @@
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 b211ccc..eb80a2b 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.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 @@
private ControlsUiController mControlsUiController;
private ViewGroup mControlsView;
+ private ViewGroup mContainer;
ActionsDialog(Context context, MyAdapter adapter, MyOverflowAdapter overflowAdapter,
GlobalActionsPanelPlugin.PanelViewController plugin,
@@ -2039,7 +2039,6 @@
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 @@
});
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 @@
}
}
- 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 @@
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 @@
@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 @@
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 14e3e93..123cf78 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 @@
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 0000000..20fc6ff
--- /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 233d24b..683c793 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.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 @@
@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 @@
* @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 @@
mActionIds = actionIds;
mForegroundExecutor = foregroundExecutor;
mBackgroundExecutor = backgroundExecutor;
+ mActivityStarter = activityStarter;
}
/**
@@ -267,13 +270,7 @@
// 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 @@
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 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 dba4343..f322489 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 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 @@
}
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 0125153..9eae3ca 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_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 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 @@
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 @@
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 @@
mSurfaceTransactionHelper = surfaceTransactionHelper;
mPipAnimationController = new PipAnimationController(context, surfaceTransactionHelper);
mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
+ mSplitDivider = divider;
}
public Handler getUpdateHandler() {
@@ -226,20 +231,21 @@
/**
* 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 @@
*/
@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 @@
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 @@
}
/**
+ * 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 ba9a30f..7897573 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 @@
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.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 @@
DeviceConfigProxy deviceConfig,
PipBoundsHandler pipBoundsHandler,
PipSnapAlgorithm pipSnapAlgorithm,
- PipSurfaceTransactionHelper surfaceTransactionHelper) {
+ PipSurfaceTransactionHelper surfaceTransactionHelper,
+ Divider divider) {
mContext = context;
mActivityManager = ActivityManager.getService();
@@ -214,7 +216,7 @@
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 @@
@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 3a2d786..6c5312d 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.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 @@
@Inject
public PipManager(Context context, BroadcastDispatcher broadcastDispatcher,
PipBoundsHandler pipBoundsHandler,
- PipSurfaceTransactionHelper surfaceTransactionHelper) {
+ PipSurfaceTransactionHelper surfaceTransactionHelper,
+ Divider divider) {
if (mInitialized) {
return;
}
@@ -249,7 +251,7 @@
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 9e574a1..e76cd51 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.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 @@
* @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 1252008..c7ce1af 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.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 @@
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 @@
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 @@
mBackgroundExecutor = backgroundExecutor;
mLocalBluetoothManager = localBluetoothManager;
mBroadcastDispatcher = broadcastDispatcher;
+ mActivityStarter = activityStarter;
setOrientation(VERTICAL);
@@ -284,7 +288,7 @@
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 @@
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 89b36da..f77ff8c 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 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 @@
* @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 2169677..becf9da 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.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 @@
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 @@
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 1a6a104..da78903 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.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 @@
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 @@
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 8dad08e..ae0a1c4 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 @@
}
/**
- * 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 1efe663..70454d4 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.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 @@
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 @@
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 @@
mScreenBitmap.setHasAlpha(false);
mScreenBitmap.prepareToDraw();
+ updateDarkTheme();
+
mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
@@ -434,7 +440,7 @@
* 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 @@
}
/**
+ * 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 @@
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 a6e083b..f68cb74 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 @@
@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 4de978c..825a7f3 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 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 0000000..2c5c3ce
--- /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 a4b1310..f5d6cb6 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.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 @@
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 @@
* 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 5aa7946..3027bd2 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 @@
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 @@
// 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 11b54ad..43b4723 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 @@
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 afb5002..02c41e5 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.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 @@
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 @@
BubbleController bubbleController,
DynamicPrivacyController privacyController,
ForegroundServiceSectionController fgsSectionController,
- DynamicChildBindController dynamicChildBindController) {
+ DynamicChildBindController dynamicChildBindController,
+ LowPriorityInflationHelper lowPriorityInflationHelper) {
mContext = context;
mHandler = mainHandler;
mLockscreenUserManager = notificationLockscreenUserManager;
@@ -124,6 +127,7 @@
mBubbleController = bubbleController;
mDynamicPrivacyController = privacyController;
mDynamicChildBindController = dynamicChildBindController;
+ mLowPriorityInflationHelper = lowPriorityInflationHelper;
}
public void setUpWithPresenter(NotificationPresenter presenter,
@@ -177,6 +181,7 @@
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 e64b423..de7e36d9 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.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 @@
BubbleController bubbleController,
DynamicPrivacyController privacyController,
ForegroundServiceSectionController fgsSectionController,
- DynamicChildBindController dynamicChildBindController) {
+ DynamicChildBindController dynamicChildBindController,
+ LowPriorityInflationHelper lowPriorityInflationHelper) {
return new NotificationViewHierarchyManager(
context,
mainHandler,
@@ -156,7 +158,8 @@
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 4e6df0a..d364689 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 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 @@
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 @@
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 @@
mBubbleController.collapseStack();
}
- mNotificationActivityStarter.onNotificationClicked(sbn, row);
+ mNotificationActivityStarter.onNotificationClicked(entry.getSbn(), row);
}
private boolean isMenuVisible(ExpandableNotificationRow row) {
@@ -107,4 +115,30 @@
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 0000000..fbf033b
--- /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 12d190b..f1cb783 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 @@
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 0000000..73c0fdc
--- /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 e6a4cff..673aa39 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 @@
private final ExpandableNotificationRowComponent.Builder
mExpandableNotificationRowComponentBuilder;
private final IconManager mIconManager;
+ private final LowPriorityInflationHelper mLowPriorityInflationHelper;
private NotificationPresenter mPresenter;
private NotificationListContainer mListContainer;
@@ -81,7 +82,8 @@
NotificationInterruptStateProvider notificationInterruptionStateProvider,
Provider<RowInflaterTask> rowInflaterTaskProvider,
ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder,
- IconManager iconManager) {
+ IconManager iconManager,
+ LowPriorityInflationHelper lowPriorityInflationHelper) {
mContext = context;
mNotifBindPipeline = notifBindPipeline;
mRowContentBindStage = rowContentBindStage;
@@ -92,6 +94,7 @@
mRowInflaterTaskProvider = rowInflaterTaskProvider;
mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder;
mIconManager = iconManager;
+ mLowPriorityInflationHelper = lowPriorityInflationHelper;
}
/**
@@ -225,11 +228,15 @@
@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 7f2f898..c975404 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 @@
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 @@
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 b9dd974..92b597b 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 @@
.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 2f0e433..dd30c89 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 @@
} 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 c613e64..ba72e28 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 @@
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 @@
}
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 9d54437..582e3e5 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 @@
mConversationProcessor,
row,
bindParams.isLowPriority,
- bindParams.isChildInGroup,
bindParams.usesIncreasedHeight,
bindParams.usesIncreasedHeadsUpHeight,
callback,
@@ -156,7 +155,6 @@
InflationProgress result = createRemoteViews(reInflateFlags,
builder,
bindParams.isLowPriority,
- bindParams.isChildInGroup,
bindParams.usesIncreasedHeight,
bindParams.usesIncreasedHeadsUpHeight,
packageContext);
@@ -285,11 +283,9 @@
}
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 @@
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 @@
ConversationNotificationProcessor conversationProcessor,
ExpandableNotificationRow row,
boolean isLowPriority,
- boolean isChildInGroup,
boolean usesIncreasedHeight,
boolean usesIncreasedHeadsUpHeight,
InflationCallback callback,
@@ -743,7 +737,6 @@
mRemoteViewCache = cache;
mContext = mRow.getContext();
mIsLowPriority = isLowPriority;
- mIsChildInGroup = isChildInGroup;
mUsesIncreasedHeight = usesIncreasedHeight;
mUsesIncreasedHeadsUpHeight = usesIncreasedHeadsUpHeight;
mRemoteViewClickHandler = remoteViewClickHandler;
@@ -781,7 +774,7 @@
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 9bd8d47..a9f83c8 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 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 d3fec69..f26ecc3 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 @@
*/
public final class RowContentBindParams {
private boolean mUseLowPriority;
- private boolean mUseChildInGroup;
private boolean mUseIncreasedHeight;
private boolean mUseIncreasedHeadsUpHeight;
private boolean mViewsNeedReinflation;
@@ -56,20 +55,6 @@
}
/**
- * 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 @@
@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 c632f3e..c6f0a13 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 @@
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 3ba6954..9e19c70 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 @@
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 53fa263..fbe3e9b 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.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 @@
*/
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 Lazy<AssistManager> mAssistManagerLazy;
- private final NotificationGroupManager mGroupManager;
- private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback;
- private final NotificationRemoteInputManager mRemoteInputManager;
- private final NotificationLockscreenUserManager mLockscreenUserManager;
- private final ShadeController mShadeController;
- private final StatusBar mStatusBar;
- private final KeyguardStateController mKeyguardStateController;
- private final ActivityStarter mActivityStarter;
+ 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 FeatureFlags mFeatureFlags;
- private final StatusBarStateController mStatusBarStateController;
- private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
- private final MetricsLogger mMetricsLogger;
- private final Context mContext;
- private final NotificationPanelViewController mNotificationPanel;
- private final NotificationPresenter mPresenter;
- private final LockPatternUtils mLockPatternUtils;
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 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 final Lazy<AssistManager> mAssistManagerLazy;
+ private final NotificationRemoteInputManager mRemoteInputManager;
+ private final NotificationGroupManager mGroupManager;
+ private final NotificationLockscreenUserManager mLockscreenUserManager;
+ private final ShadeController mShadeController;
+ private final KeyguardStateController mKeyguardStateController;
+ 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 StatusBarNotificationActivityStarterLogger mLogger;
+
+ private final StatusBar mStatusBar;
+ private final NotificationPresenter mPresenter;
+ private final NotificationPanelViewController mNotificationPanel;
+ private final ActivityLaunchAnimator mActivityLaunchAnimator;
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;
- mHeadsUpManager = headsUpManager;
- mActivityLaunchAnimator = activityLaunchAnimator;
- mBarService = statusBarService;
mCommandQueue = commandQueue;
+ mMainThreadHandler = mainThreadHandler;
+ mBackgroundHandler = backgroundHandler;
+ mUiBgExecutor = uiBgExecutor;
+ mEntryManager = entryManager;
+ mNotifPipeline = notifPipeline;
+ mNotifCollection = notifCollection;
+ mHeadsUpManager = headsUpManager;
+ mActivityStarter = activityStarter;
+ mBarService = statusBarService;
+ mStatusBarStateController = statusBarStateController;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardManager = keyguardManager;
mDreamManager = dreamManager;
+ mBubbleController = bubbleController;
+ mAssistManagerLazy = assistManagerLazy;
mRemoteInputManager = remoteInputManager;
+ mGroupManager = groupManager;
mLockscreenUserManager = lockscreenUserManager;
mShadeController = shadeController;
+ mKeyguardStateController = keyguardStateController;
+ mNotificationInterruptStateProvider = notificationInterruptStateProvider;
+ mLockPatternUtils = lockPatternUtils;
+ mStatusBarRemoteInputCallback = remoteInputCallback;
+ mActivityIntentHelper = activityIntentHelper;
+
+ mFeatureFlags = featureFlags;
+ mMetricsLogger = metricsLogger;
+ mLogger = logger;
+
// 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;
- mFeatureFlags = featureFlags;
- mNotifPipeline = notifPipeline;
- mNotifCollection = notifCollection;
+ mPresenter = presenter;
+ mNotificationPanel = panel;
+ mActivityLaunchAnimator = activityLaunchAnimator;
+
if (!mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@Override
@@ -192,11 +218,6 @@
}
});
}
-
- mStatusBarRemoteInputCallback = remoteInputCallback;
- mMainThreadHandler = mainThreadHandler;
- mActivityIntentHelper = activityIntentHelper;
- mBubbleController = bubbleController;
}
/**
@@ -207,6 +228,8 @@
*/
@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 @@
// 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 @@
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 @@
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 @@
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 @@
}
}
- 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 @@
} 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 @@
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 @@
});
// 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 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 @@
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 KeyguardStateController mKeyguardStateController;
- private final MetricsLogger mMetricsLogger;
- private final LockPatternUtils mLockPatternUtils;
- private final Handler mMainThreadHandler;
- private final Handler mBackgroundHandler;
- private final Executor mUiBgExecutor;
- private final ActivityIntentHelper mActivityIntentHelper;
- private final BubbleController mBubbleController;
- private NotificationPanelViewController mNotificationPanelViewController;
- private NotificationInterruptStateProvider mNotificationInterruptStateProvider;
private final ShadeController mShadeController;
- private NotificationPresenter mNotificationPresenter;
- private ActivityLaunchAnimator mActivityLaunchAnimator;
+ private final KeyguardStateController mKeyguardStateController;
+ private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
+ private final LockPatternUtils mLockPatternUtils;
+ private final StatusBarRemoteInputCallback mRemoteInputCallback;
+ private final ActivityIntentHelper mActivityIntentHelper;
+
+ private final FeatureFlags mFeatureFlags;
+ private final MetricsLogger mMetricsLogger;
+ private final StatusBarNotificationActivityStarterLogger mLogger;
+
private StatusBar mStatusBar;
+ private NotificationPresenter mNotificationPresenter;
+ private NotificationPanelViewController mNotificationPanelViewController;
+ private ActivityLaunchAnimator mActivityLaunchAnimator;
@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 @@
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 @@
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 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 0000000..d118747
--- /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 cc6d607..8acfbf2 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 @@
}
/**
+ * 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 0000000..aefdc99
--- /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 0000000..c03e10e
--- /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 f6ee46b..e3f25c6 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 @@
@Captor
private lateinit var controlLoadCallbackCaptor:
ArgumentCaptor<ControlsBindingController.LoadCallback>
+
@Captor
private lateinit var broadcastReceiverCaptor: ArgumentCaptor<BroadcastReceiver>
@Captor
@@ -97,6 +98,7 @@
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 @@
}
}
+ canceller = DidRunRunnable()
+ `when`(bindingController.bindAndLoad(any(), any())).thenReturn(canceller)
+
controller = ControlsControllerImpl(
wrapper,
delayableExecutor,
@@ -266,7 +271,7 @@
assertTrue(favorites.isEmpty())
assertFalse(data.errorOnLoad)
- })
+ }, Consumer {})
verify(bindingController).bindAndLoad(eq(TEST_COMPONENT),
capture(controlLoadCallbackCaptor))
@@ -301,7 +306,7 @@
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 @@
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 @@
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 @@
@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 @@
}
@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 @@
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 @@
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 9112b65..9a32b1d 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.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 @@
private DelayableExecutor mBackgroundExecutor;
@Mock
private LocalBluetoothManager mLocalBluetoothManager;
+ @Mock
+ private ActivityStarter mActivityStarter;
@Before
public void setup() throws Exception {
@@ -98,7 +101,7 @@
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 4ac5912d..8a8d227 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 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 @@
@Mock
private RecordingController mController;
@Mock
+ private ActivityStarter mActivityStarter;
+ @Mock
private QSTileHost mHost;
private TestableLooper mTestableLooper;
@@ -61,10 +64,11 @@
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 @@
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 fb40177..23099d7 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 @@
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 @@
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 e55ea41..d41b6cf 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.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 @@
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 855f524..2894abb8 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.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 @@
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 96a58e2..ad3bd71 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 @@
}
@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 dd28687..1afe132 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 @@
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 0000000..00f37ae
--- /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 1258805..056168b 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 9c36192..ac468dd 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 9f84ce4..7d5bad3 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 8855822..0913504 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 eba50eb..dce70da 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 5b0e488..b0774ec 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 5966c71..a8acebe 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 ed58d73..94fb2d8 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 8d9880a..aea02b9 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 2361b9d..de23272 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 6752b51..88b795c 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 5fdd53a..8c1b83b 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 2775dfa..f413e70 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 9046cd5..f057d78 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 3b9f537..b3c986b 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 56b88a5..769e0120 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 56b88a5..769e0120 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 56b88a5..769e0120 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 56b88a5..769e0120 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 7f47fc8..f1674be 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 e4618b8..63689f4 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 8dc1575..9a34ed5 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 872c8a7..0970341 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 6c4605e..632019e 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 bc2ee23..2e21c85 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 ff0fca6..413db3f 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 1f5df0e..eb2e4ba 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 daf7c9d..22259c5 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 0d16a1d..ded82fc 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 9d6b02f..7cbbc2d 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 9c29d9a..08af81b 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 d0d25bb..827c135 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 3129659..eb68d6b 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 8ba6435..912941e 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 1e093ab..a4e175a 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 f5769d5..e9f6670 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 e0b3724..ffb9196 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 c002c44..7adcb47 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 314bde0..f68a730 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 7bbd81d..7c22e82 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 7fd87a1..0857d06 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 2f85224..536e3d1 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 f11a83ea..32f5492 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 57f24f5..156b247 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 7985485..18ee5fd 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 78f1585..b127670 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 ebff8ac..8427baf 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 54d0048..aa2d699 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 0000000..19d659c
--- /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 0000000..8995430
--- /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 0000000..54f3b53
--- /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 0000000..e215141c
--- /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 0000000..1fd8e4c
--- /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 0000000..1abe4f3
--- /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 0000000..38dbd1e
--- /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 0000000..04b44db
--- /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 0000000..579d1be
--- /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 0000000..9ce3efe
--- /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 0000000..46d4c35
--- /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 0000000..cc13860
--- /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 0000000..92c3ae1
--- /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 0000000..967eb4d
--- /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 0000000..5fb4974
--- /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 0000000..45647f9
--- /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 0000000..45647f9
--- /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 0000000..45647f9
--- /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 0000000..45647f9
--- /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 0000000..7877074
--- /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 0000000..08edd81
--- /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 0000000..79f51d0
--- /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 0000000..2da5f8a
--- /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 0000000..2073f28
--- /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 0000000..e21b2a0
--- /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 0000000..88b0b13
--- /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 0000000..3b781bc
--- /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 0000000..51d7203
--- /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 0000000..008ccb4
--- /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 0000000..f2e3b4d
--- /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 0000000..b11839d
--- /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 0000000..0a5aca2
--- /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 0000000..21c689a4
--- /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 0000000..689d9287
--- /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 0000000..a5f4d19
--- /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 0000000..fc7e8aa
--- /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 0000000..6456dd1
--- /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 0000000..46b24bd
--- /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 0000000..e6eb277
--- /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 0000000..aeddd71
--- /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 0000000..255f0a2
--- /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 0000000..2bceb1c
--- /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 0000000..ed76930
--- /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 0000000..6e50494
--- /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 0000000..d68128b
--- /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 0000000..03e134a
--- /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 0000000..652cedc
--- /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 0000000..2219722
--- /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 0000000..227f9e3
--- /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 0000000..ec43885
--- /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 0000000..e263573
--- /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 0000000..adf845d
--- /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 0000000..f65c451
--- /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 0000000..4118e77
--- /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 0000000..3685358
--- /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 0000000..2a73300
--- /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 0000000..1d88894
--- /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 0000000..8038815
--- /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 0000000..819833e
--- /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 0000000..65e4380
--- /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 0000000..d886617
--- /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 0000000..bfd45ca
--- /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 0000000..d886617
--- /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 0000000..8d87a9e5
--- /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 0000000..dbdb9eb
--- /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 0000000..d8301e4
--- /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 0000000..bef7136
--- /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 0000000..3202c62
--- /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 0000000..37f6ad2
--- /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 0000000..5566d03
--- /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 0000000..9765acd
--- /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 0000000..cf850c9
--- /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 0000000..ea04821
--- /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 0000000..937d34d
--- /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 0000000..f781fae
--- /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 0000000..8d5d4653
--- /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 0000000..80cab33
--- /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 0000000..c05932a
--- /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 0000000..d820eee
--- /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 0000000..726148a
--- /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 0000000..b7cb045
--- /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 0000000..af91aff
--- /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 0000000..28e6b80
--- /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 0000000..05b90692
--- /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 0000000..11eb666
--- /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 9dadd49..ce9ff60 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 618df90..0000000
--- 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 0000000..9bfa531
--- /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 0000000..5949dfa
--- /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 0000000..8467f9b
--- /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 0000000..9776bd8
--- /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 0000000..e6d3eaf
--- /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 0000000..4c8a1df
--- /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 0000000..edfa41e
--- /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 0000000..f563981
--- /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 0000000..d8ecd2e
--- /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 0000000..b85fd5e
--- /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 0000000..a357215
--- /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 0000000..91196be
--- /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 0000000..1968900
--- /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 0000000..eb3f8c5
--- /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 0000000..56c3d81
--- /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 0000000..dd1a197
--- /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 0000000..dd1a197
--- /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 0000000..dd1a197
--- /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 0000000..dd1a197
--- /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 0000000..d3347aa
--- /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 0000000..2f0504f
--- /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 0000000..2d8f882
--- /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 0000000..8493c470
--- /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 0000000..33bccab
--- /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 0000000..cf8a0cc
--- /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 0000000..6a3ab80
--- /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 0000000..ffb9bf60
--- /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 0000000..768bce3
--- /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 0000000..0c4195a
--- /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 0000000..e9d33a7
--- /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 0000000..aa418ac
--- /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 0000000..51c524a
--- /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 0000000..164e45e
--- /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 0000000..e76c0a4
--- /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 0000000..2b817f8
--- /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 0000000..a338d9c
--- /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 0000000..77769c2
--- /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 0000000..5267b51
--- /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 0000000..66a9a6d
--- /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 0000000..d8ad880
--- /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 0000000..1ddd6b4
--- /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 0000000..cf5a137
--- /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 0000000..68ae68b
--- /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 0000000..17185ba
--- /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 0000000..6a9fb98
--- /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 0000000..bcc4b57
--- /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 0000000..011c2c1
--- /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 0000000..5cb2f3b
--- /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 0000000..4cbfd88
--- /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 0000000..9cf4eaf
--- /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 0000000..47c82c1
--- /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 0000000..ad9e809
--- /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 0000000..e708cb8
--- /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 0000000..ba54622
--- /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 0000000..57db484a2
--- /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 0000000..617c50d
--- /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 0000000..b08133f
--- /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 0000000..1ad4ca3
--- /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 0000000..88def56
--- /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 0000000..f9890ab
--- /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 0000000..ce3b884
--- /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 0000000..7e883ea
--- /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 0000000..ce3b884
--- /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 0000000..1009417
--- /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 0000000..88683be
--- /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 0000000..176bcdb
--- /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 0000000..b9e2127
--- /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 0000000..e8140e6
--- /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 0000000..61e698d
--- /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 0000000..b4c411c
--- /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 0000000..4f543e4
--- /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 0000000..ac347ab
--- /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 0000000..0e43759
--- /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 0000000..9360297
--- /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 0000000..9c4d7e0
--- /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 0000000..a7c78a5
--- /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 0000000..93da2c3
--- /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 0000000..ee0dcd2
--- /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 0000000..41cd28e
--- /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 0000000..c847bc9
--- /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 0000000..a74326f
--- /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 0000000..d737003
--- /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 0000000..f378a9d
--- /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 0000000..ea01b94
--- /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 0000000..32f6df5
--- /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 9dadd49..ce9ff60 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-mcc311-mnc490/strings.xml b/packages/Tethering/res/values-mcc311-mnc490/strings.xml
deleted file mode 100644
index 618df90..0000000
--- a/packages/Tethering/res/values-mcc311-mnc490/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-mcc312-mnc530/strings.xml b/packages/Tethering/res/values-mcc312-mnc530/strings.xml
deleted file mode 100644
index 618df90..0000000
--- a/packages/Tethering/res/values-mcc312-mnc530/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-mk/strings.xml b/packages/Tethering/res/values-mk/strings.xml
index 0fab8aa..9ad9b9a 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 fd7e556..9db79ce 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 4596577..42d1edb 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 85c9ade..13995b6 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 ec6bdbd..d6a67f3 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 83978b6..49f6b88 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 9abf32d..9594e0a 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 c886929..72ae3a8 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 0ec4bff..18b2bbf 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 4576857..a15a6db 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 deddf2e..a8235e4 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 48d8468..ccb017d 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 32c22b8..a0a4745 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 641e22f..e3f03fc 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 32c22b8..a0a4745 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 f861f73..5706a4a 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 027cb41..7cb6f7d 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 7d8599f..ec34c22 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 a8fe297..43e787c 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 b5e5e38..5943362 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 fdd4906..21e1155 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 9fab34589..e2e4dc6 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 10eeb0f..72702c2 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 3353963..65e4aa8 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 b1e5cc2..4aba62d 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 aae40de..1f91791 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 1b80056..44171c0 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 12863f9..7347dd3 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 bfcf1ac..32030f1 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 8e159c0..1ca89b3 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 89195d4..d72c7d4 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 0ac4d4a..af3b2eb 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 85a4db8..21a0735 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 ff1fe03..98e3b4b 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 0de39fa..9cafd42 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 9a117bb..9d738a7 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 8fe10d8..f210f87 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 66fbefca..83c99d2 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 bbba3f3..16ae8ad 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 4fa60d4..d63c7c5 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 85a23fb..55344fc 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 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 05cf68e..4e16c49 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 @@
}
@VisibleForTesting
+ boolean isTetheringActive() {
+ return mActiveTetheringRequests.size() > 0;
+ }
+
+ @VisibleForTesting
protected static class UserRestrictionActionListener {
private final UserManager mUserManager;
private final Tethering mWrapper;
@@ -1043,13 +1048,14 @@
return;
}
- // Restricted notification is shown when tethering function is disallowed on
- // user's device.
- mNotificationUpdater.notifyTetheringDisabledByRestriction();
+ 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();
-
+ // 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 f490cc4..d03deda 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.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 @@
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 @@
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {
- ENABLE_NOTIFICATION_ID,
RESTRICTED_NOTIFICATION_ID,
NO_UPSTREAM_NOTIFICATION_ID,
ROAMING_NOTIFICATION_ID
@@ -223,7 +214,6 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 6b751af..3305ed0 100644
--- a/packages/Tethering/tests/integration/Android.bp
+++ b/packages/Tethering/tests/integration/Android.bp
@@ -69,6 +69,7 @@
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 26517ce..08cfb30 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 @@
],
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
similarity index 81%
rename from packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt
rename to packages/Tethering/tests/unit/common/android/net/TetheredClientTest.kt
index a20a0df..55c59dd 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_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 @@
class TetheredClientTest {
@Test
fun testParceling() {
+ assertParcelSane(TEST_ADDRINFO1, fieldCount = 2)
assertParcelSane(makeTestClient(), fieldCount = 3)
}
@@ -65,7 +68,7 @@
// 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 @@
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 04f31a7..745468f 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.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.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.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 @@
@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 @@
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 @@
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 @@
.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 @@
}
@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 @@
}
@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 @@
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 @@
}
@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 @@
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 cf05483..0c86eeb 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 @@
}
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 @@
}
@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 = 0;
+
+ runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
+ expectedInteractionsWithShowNotification);
+ }
+
+ @Test
+ public void testDisallowTetheringWhenTetheringIsActive() throws Exception {
+ final boolean isTetheringActive = true;
final boolean currDisallow = false;
final boolean nextDisallow = true;
final int expectedInteractionsWithShowNotification = 1;
- runUserRestrictionsChange(currDisallow, nextDisallow, emptyActiveIfacesList,
+ runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
expectedInteractionsWithShowNotification);
}
@Test
- public void testDisallowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
- final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
- final boolean currDisallow = false;
- final boolean nextDisallow = true;
- final int expectedInteractionsWithShowNotification = 1;
-
- runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
- 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 b000146..a05a389 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 0000000..a810251
--- /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 0000000..e8608a5
--- /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 0000000..4e265fd
--- /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 0000000..726d1aa
--- /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 7139313..0dfaf81 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 0000000..b3f353a
--- /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 0000000..1d291c9
--- /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 0000000..df4525d
--- /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 0000000..89ee527
--- /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 38f515f..be31fb9 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 0000000..8d298f7
--- /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/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_screenshot.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_screenshot.xml
new file mode 100644
index 0000000..ed90b85
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/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="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 0000000..b699a44
--- /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 0000000..36dd3ba
--- /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 730b9a5..6d637be 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -112,7 +112,6 @@
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 132b692..da9bdf3 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 @@
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 ce65110..4009caf 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -603,8 +603,7 @@
}
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 2bbf278..97a5cfe 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1146,7 +1146,7 @@
&& 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 @@
// 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 58c388e..b09d741 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -122,7 +122,6 @@
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 @@
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 @@
}
};
- 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 @@
}
@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 @@
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 @@
@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 @@
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 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 @@
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 debc2a1..27c3ff1 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.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 @@
* 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 21760cd..419389f 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.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 @@
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 @@
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 @@
}
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 @@
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 @@
// Cleanup.
if (newService) {
- app.services.remove(r);
+ app.stopService(r);
r.setProcess(null);
}
@@ -3362,7 +3361,7 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
}
if (!allowRestart) {
- app.services.clear();
+ app.stopAllServices();
app.clearBoundClientUids();
// Make sure there are no more restarting services for this process.
@@ -4920,8 +4917,8 @@
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 3fdf541..5d7590d 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 @@
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 @@
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 b1fc029..50d2cab 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 @@
}
// 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 dbad562..b647818 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 @@
@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 2d6ef81..ad85853 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 @@
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 @@
}
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 e28464a..c9ee472 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 @@
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 @@
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 61ebc36..a1ec07c 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 @@
// 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 @@
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 @@
}
}
+ /**
+ * 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 @@
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 @@
}
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 546025a..c7c2510 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 @@
// 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 @@
}
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 @@
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 c2c79d3..032ad63 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.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 @@
}
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 c17ed3e..3e97a1e 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.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 @@
// 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 @@
+ " 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 @@
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 @@
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 @@
}
@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 @@
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 @@
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 @@
+ address + " codec=" + a2dpCodec).printLog(TAG));
}
}
+ mmi.record();
}
/*package*/ void onMakeA2dpDeviceUnavailableNow(String address, int a2dpCodec) {
@@ -399,6 +504,9 @@
/*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 @@
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 @@
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 @@
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 @@
AudioSystem.DEVICE_STATE_AVAILABLE, "", "",
"android"); // reconnect
}
+ mmi.record();
}
/*package*/ void onSaveSetPreferredDevice(int strategy, @NonNull AudioDeviceAttributes device) {
@@ -535,6 +658,12 @@
+ 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 @@
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 @@
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 @@
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 @@
toRemove.add(deviceInfo.mDeviceAddress);
}
});
+ new MediaMetrics.Item(mMetricsId + "disconnectA2dpSink")
+ .record();
toRemove.stream().forEach(deviceAddress -> makeA2dpSrcUnavailable(deviceAddress));
}
}
@@ -615,6 +755,8 @@
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 @@
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 @@
@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 @@
// 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 @@
mApmConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
// Remove A2DP routes as well
setCurrentAudioRouteNameIfPossible(null);
+ mmi.record();
}
@GuardedBy("mDevicesLock")
@@ -862,6 +1015,14 @@
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 @@
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 @@
@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 @@
// 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 f840f2d..7cac376 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.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 @@
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 @@
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 @@
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 @@
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 @@
}
// 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 @@
}
// 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 @@
/** @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 @@
/** @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 @@
!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 @@
&& 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 @@
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 @@
+ 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 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 @@
}
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 @@
}
}
+ /**
+ * 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 add620e..5913567 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 @@
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 @@
mCaller = caller;
mGroupName = null;
mAudioAttributes = null;
+ logMetricEvent();
}
/** used for VOL_SET_HEARING_AID_VOL*/
@@ -132,6 +134,7 @@
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
+ logMetricEvent();
}
/** used for VOL_SET_AVRCP_VOL */
@@ -144,6 +147,7 @@
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
+ logMetricEvent();
}
/** used for VOL_VOICE_ACTIVITY_HEARING_AID */
@@ -156,6 +160,7 @@
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
+ logMetricEvent();
}
/** used for VOL_MODE_CHANGE_HEARING_AID */
@@ -168,6 +173,7 @@
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
+ logMetricEvent();
}
/** used for VOL_SET_GROUP_VOL */
@@ -179,6 +185,102 @@
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 93d1bed..accb90c 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 @@
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 @@
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 bfab991..26281b7 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.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 @@
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 @@
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 @@
* */
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 f4d7f9a..36d69c9 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 @@
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 @@
// 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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
} 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 @@
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 @@
}
}
- // 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 @@
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 b4f7cdb..02d499f 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.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 @@
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 @@
}
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 @@
}
@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 48e30bf..bafeb77 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 @@
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 f0a505d..2b56569 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 @@
* 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 @@
* 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 1cf27ff..cc7915c 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.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 static final int NETWORK_COUNTRY_CHANGED = 2;
+ private static final int SUBSCRIPTION_CHANGED = 3;
+ private static final int UPDATE_AIRPLANE_MODE_STATUS = 4;
+
+ // 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 final Context mContext;
- private final ArrayList<Integer> mEmergencyCallMccNumbers;
-
- private final Object mLock = new Object();
-
- private TelephonyManager mTelephonyManager;
+ // 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();
- }
- }
-
- @Override
- public void onCellLocationChanged(CellLocation location) {
- if (!isEmergencyAffordanceNeeded()) {
- requestCellScan();
- }
- }
- };
- private BroadcastReceiver mAirplaneModeReceiver = 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();
- }
- }
- };
- private boolean mSimNeedsEmergencyAffordance;
- private boolean mNetworkNeedsEmergencyAffordance;
+ private boolean mAnySimNeedsEmergencyAffordance;
+ private boolean mAnyNetworkNeedsEmergencyAffordance;
+ private boolean mEmergencyAffordanceNeeded;
+ private boolean mAirplaneModeEnabled;
private boolean mVoiceCapable;
- private void requestCellScan() {
- mHandler.obtainMessage(CELL_INFO_STATE_CHANGED).sendToTarget();
- }
+ private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ 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 SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener
= new SubscriptionManager.OnSubscriptionsChangedListener() {
@@ -116,207 +106,200 @@
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()) {
- return;
- }
+ if (DBG) Slog.d(TAG, "handleInitializeState");
+ handleUpdateAirplaneModeStatus();
+ handleUpdateSimSubscriptionInfo();
+ updateNetworkCountry();
updateEmergencyAffordanceNeeded();
}
- private boolean handleUpdateSimSubscriptionInfo() {
- boolean neededBefore = simNeededAffordanceBefore();
- boolean neededNow = neededBefore;
+ private void handleThirdPartyBootPhase() {
+ if (DBG) Slog.d(TAG, "handleThirdPartyBootPhase");
+ mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+ mVoiceCapable = mTelephonyManager.isVoiceCapable();
+ if (!mVoiceCapable) {
+ updateEmergencyAffordanceNeeded();
+ return;
+ }
+
+ 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 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) {
+ private void handleNetworkCountryChanged(String countryIso, int slotId) {
+ if (DBG) {
+ Slog.d(TAG, "handleNetworkCountryChanged: countryIso=" + countryIso
+ + ", slotId=" + slotId);
+ }
+
+ if (TextUtils.isEmpty(countryIso) && mAirplaneModeEnabled) {
+ Slog.w(TAG, "Ignore empty countryIso report when APM is on.");
+ return;
+ }
+
+ updateNetworkCountry();
+
+ updateEmergencyAffordanceNeeded();
+ }
+
+ 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;
+ }
+ }
+
+ mAnyNetworkNeedsEmergencyAffordance = needsAffordance;
+
+ updateEmergencyAffordanceNeeded();
+ }
+
+ private boolean isoRequiresEmergencyAffordance(String iso) {
+ return mEmergencyCallCountryIsos.contains(iso);
+ }
+
+ 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(),
- EMERGENCY_SIM_INSERTED_SETTING,
- simNeedsEmergencyAffordance ? 1 : 0);
- }
- if (simNeedsEmergencyAffordance != mSimNeedsEmergencyAffordance) {
- mSimNeedsEmergencyAffordance = simNeedsEmergencyAffordance;
- updateEmergencyAffordanceNeeded();
+ Settings.Global.EMERGENCY_AFFORDANCE_NEEDED,
+ mEmergencyAffordanceNeeded ? 1 : 0);
}
}
- private boolean simNeededAffordanceBefore() {
- return Settings.Global.getInt(mContext.getContentResolver(),
- EMERGENCY_SIM_INSERTED_SETTING, 0) != 0;
+ 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 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();
+ private final class BinderService extends Binder {
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) {
+ return;
}
- 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;
- }
- }
- if (stopScanningAfterScan) {
- stopScanning();
- } else {
- onCellScanFinishedUnsuccessful();
- }
- setNetworkNeedsEmergencyAffordance(false);
- return false;
- }
- private void setNetworkNeedsEmergencyAffordance(boolean needsAffordance) {
- synchronized (mLock) {
- mNetworkNeedsEmergencyAffordance = needsAffordance;
- updateEmergencyAffordanceNeeded();
+ dumpInternal(new IndentingPrintWriter(pw, " "));
}
}
-
- private void onCellScanFinishedUnsuccessful() {
- synchronized (mLock) {
- mScansCompleted++;
- if (mScansCompleted >= NUM_SCANS_UNTIL_ABORT) {
- stopScanning();
- }
- }
- }
-
- private boolean mccRequiresEmergencyAffordance(int mcc) {
- return mEmergencyCallMccNumbers.contains(mcc);
- }
}
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index 44e973e..393e8db 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 @@
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 @@
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 @@
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 @@
.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 @@
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 @@
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 bfc76df..e846daf 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 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 f7fb9b7..69a7ce90 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.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 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 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 8e9af1c..341e974 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 @@
}
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 @@
}
@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 @@
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 @@
}
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 d432fc8..6d7b410 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 @@
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 @@
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 @@
|| 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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 96da649..13892ba0 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 java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -186,6 +187,17 @@
}
/**
+ * 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 d36d038..118fdcb 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.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 @@
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 @@
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 (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;
+ }
+ return false;
+ }
- if (matchesAnyFilter(intent, activity, null /*protectedBroadcasts*/)) {
- return true;
- }
- }
- for (int r = ArrayUtils.size(potentialTarget.getReceivers()) - 1; r >= 0; r--) {
- ParsedActivity receiver = potentialTarget.getReceivers().get(r);
- if (!receiver.isExported()) {
+ 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 ae9c384..dec3f1a 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.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.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 @@
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 @@
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 @@
*/
@Override
public @Nullable IDataLoader getDataLoader(int dataLoaderId) {
- synchronized (mLock) {
+ synchronized (mServiceConnections) {
DataLoaderServiceConnection serviceConnection = mServiceConnections.get(
dataLoaderId, null);
if (serviceConnection == null) {
@@ -157,14 +156,14 @@
}
/**
- * 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 @@
}
}
- 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 @@
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
mDataLoader = IDataLoader.Stub.asInterface(service);
- synchronized (mLock) {
+ if (mDataLoader == null) {
+ onNullBinding(className);
+ return;
+ }
+ synchronized (mServiceConnections) {
+ if (mServiceConnections.get(mId) != null) {
+ // Another connection already bound for this ID.
+ mContext.unbindService(this);
+ return;
+ }
mServiceConnections.append(mId, this);
}
- try {
- mDataLoader.create(mId, mParams, mControl, mListener);
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to create data loader service.", e);
- }
+ 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 @@
}
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 4cfd1ab7..3367cd5 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 @@
@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 6b1ef3a..8e7eaf6 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 @@
"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 @@
}
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 @@
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 @@
}
}
- 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 7adafe3..28987ed 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 @@
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 @@
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 2aa6e573..3614cc0 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 @@
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 @@
}
}
- 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 780b234..4a1a6a7 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.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 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 d89605a..da07223 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 @@
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 2256b62..af14d84 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 @@
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 0000000..e5d0370
--- /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 1afec9c..6fd7250 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.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 @@
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 @@
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 735a9e4..5311369 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.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 @@
// 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 abccf99..785ca90 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.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.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 @@
*/
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 @@
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 @@
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 @@
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 @@
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 @@
}, 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 @@
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 @@
private final long mRecurringAccessibilityEventsIntervalMillis;
+ private final IntArray mEmbeddedDisplayIdList = new IntArray(0);
+
public WindowsForAccessibilityObserver(WindowManagerService windowManagerService,
int displayId,
WindowsForAccessibilityCallback callback) {
@@ -1176,6 +1232,21 @@
}
}
+ 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 2648c86..130da2d 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 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 @@
task.computeConfigResourceOverrides(newConfig, task.getParent().getConfiguration());
}
schedulePictureInPictureModeChanged(newConfig);
- scheduleMultiWindowModeChanged(newConfig);
+ if (shouldScheduleMultiWindowModeChange) {
+ scheduleMultiWindowModeChanged(newConfig);
+ }
}
}
@@ -1414,11 +1419,10 @@
}
/**
- * @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 @@
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 @@
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 @@
@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 ff43e77..2ab03ce 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 @@
}
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 0754a34..8edc84f 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 @@
// 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 @@
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 93a7574..5220fb2 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.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 @@
/** 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 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 @@
}
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 57cdb0b..8b14095 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 @@
}
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 a512337..9b34bd1 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.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 @@
}
@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 f05783b..2c8c820 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 @@
}
}
+ @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 @@
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 e261632..8f7fc9e 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 @@
}
}
}
+
+ /**
+ * 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 61a199a..5a9bf80 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 @@
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 1ca82ce..351743f 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 @@
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 @@
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 @@
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 @@
return true;
}
+ void onSurfaceTransactionApplied() {
+ mIsLeashReadyForDispatching = true;
+ }
+
private void setClientVisible(boolean clientVisible) {
if (mClientVisible == clientVisible) {
return;
@@ -334,6 +341,13 @@
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 4ac319d..765f980 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 @@
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 6721ef8..00a4be3 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 @@
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 @@
}
/**
- * 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 @@
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 7bdd9c9..77841dc 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 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 @@
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 9d44cad..86e0818 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 @@
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 df5cfee..93c6b6e 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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 25791c7..3dc6723 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 @@
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 @@
mDisplayContent = displayContent;
mRootWindowContainer = service.mRoot;
mAtmService = service.mAtmService;
+
+ mAssistantOnTopOfDream = mWmService.mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_assistantOnTopOfDream);
}
/**
@@ -327,55 +334,80 @@
}
/**
+ * 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 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;
+ }
+ }
+
+ if (stack.isAlwaysOnTop()) {
+ // 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;
+ }
+ }
+ 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.
- * This will make sure that pinned stack always stays on top.
+ *
+ * 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) {
- 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;
- break;
- }
- }
-
+ private int findPositionForStack(int requestedPosition, ActivityStack stack, boolean adding) {
// The max possible position we can insert the stack at.
- int maxPosition = POSITION_TOP;
+ int maxPosition = findMaxPositionForStack(stack);
// 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;
- }
- // 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;
- }
+ 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 adc50bf..306c100 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 @@
}
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 @@
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 @@
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 @@
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 203ca25..5f3c633 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 @@
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 f3e2992..591bc54 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 @@
*/
@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 @@
* @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 @@
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 51095ee..8eb4b26 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.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_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 @@
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 @@
@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 @@
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 @@
mInputManagerCallback.dump(pw, " ");
mTaskSnapshotController.dump(pw, " ");
+ if (mAccessibilityController != null) {
+ mAccessibilityController.dump(pw, " ");
+ }
if (dumpAll) {
final WindowState imeWindow = mRoot.getCurrentInputMethodWindow();
@@ -7656,15 +7678,8 @@
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 194ed3e..41bd707 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.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.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 @@
// 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 @@
// 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 @@
/** 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 @@
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 @@
* 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 @@
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 @@
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 @@
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 @@
}
}
+ /**
+ * 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 ef690e1..bbe5d94 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 @@
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 9957707..bfe3b28 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 @@
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 @@
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 e32a343..6cf8133 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 @@
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 @@
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 @@
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 @@
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 @@
});
}
- 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 @@
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 6e2e2c5..99deab4 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 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 7b84555..5d5e424 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 @@
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 @@
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 @@
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 @@
}
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 @@
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 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 @@
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 @@
}
}
+ 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 @@
}
}
- 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 @@
}
/**
- * 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 @@
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 {
+
+ if (alarmTime == 0) {
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);
+ 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 @@
}
}
- 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 @@
}
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 d9db17e..da716ea 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 @@
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 @@
*/
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 @@
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 @@
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 @@
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 @@
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 b13d330..de639c5 100644
--- a/services/incremental/Android.bp
+++ b/services/incremental/Android.bp
@@ -19,6 +19,21 @@
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 @@
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 fc8c6fe..8476674 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::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::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 f423119..a1b4f24 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 @@
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 @@
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 @@
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 @@
}
} // 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 @@
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 @@
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 @@
runJobProcessing();
});
- mountExistingImages();
+ const auto mountedRootNames = adoptMountedInstances();
+ mountExistingImages(mountedRootNames);
}
IncrementalService::~IncrementalService() {
@@ -268,15 +296,7 @@
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 @@
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());
- }
+ 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, "\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));
+ 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 @@
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 @@
}
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
}
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));
}
- return 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()) {
+ 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 normalizePathToStorageLocked(storageInfo, path);
+ return path::join(bindIt->second.sourceDir, path::relativize(bindIt->first, normPath));
+}
+
+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(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::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 @@
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 @@
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 @@
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,12 +935,31 @@
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, std::string_view path) const {
+ const auto ifs = getIfs(storage);
+ if (!ifs) {
+ return {};
+ }
+ const auto normPath = normalizePathToStorage(*ifs, storage, path);
+ if (normPath.empty()) {
+ return {};
+ }
+ return mIncFs->getMetadata(ifs->control, normPath);
}
RawMetadata IncrementalService::getMetadata(StorageId storage, FileId node) const {
@@ -945,47 +970,6 @@
return mIncFs->getMetadata(ifs->control, node);
}
-std::vector<std::string> IncrementalService::listFiles(StorageId storage) 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;
-}
-
bool IncrementalService::startLoading(StorageId storage) const {
DataLoaderStubPtr dataLoaderStub;
{
@@ -1003,16 +987,216 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
}
// 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
[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::destroy() {
- mService.mDataLoaderManager->destroyDataLoader(mId);
+ mService.mDataLoaderManager->unbindFromDataLoader(mId);
return true;
}
@@ -1575,6 +1794,8 @@
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 @@
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 @@
}
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 bd01d77..1de0070 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 @@
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 @@
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 @@
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 @@
};
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 0000000..abadbbf
--- /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 48894c6..0e50c4d 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>
+
+#include <string>
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;
-}
-
-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};
-
- // 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 bf8e696..85f7441 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 @@
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 @@
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 @@
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<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 @@
return getJavaVm(env);
}
-} // namespace android::os::incremental
+} // namespace android::incremental
diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h
index 142bf2e..3792830 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 @@
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 @@
JavaVM* const mJvm;
};
-} // namespace android::os::incremental
+} // namespace android::incremental
diff --git a/services/incremental/path.cpp b/services/incremental/path.cpp
index 0d86f2a..338659d 100644
--- a/services/incremental/path.cpp
+++ b/services/incremental/path.cpp
@@ -44,7 +44,7 @@
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 bfe92f4..2205bfe 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 @@
.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 @@
}
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
mRootDir.path);
mDataLoaderParcel.packageName = "com.test";
mDataLoaderParcel.arguments = "uri";
- mDataLoaderManager->destroyDataLoaderSuccess();
+ mDataLoaderManager->unbindFromDataLoaderSuccess();
mIncrementalService->onSystemReady();
}
@@ -434,7 +443,7 @@
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, 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, 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
mVold->mountIncFsSuccess();
mIncFs->makeFileSuccess();
mVold->bindMountSuccess();
- mDataLoaderManager->initializeDataLoaderSuccess();
+ mDataLoaderManager->bindToDataLoaderSuccess();
mDataLoaderManager->getDataLoaderSuccess();
TemporaryDir tempDir;
int storageId =
@@ -717,29 +727,15 @@
auto first = "first"sv;
auto second = "second"sv;
auto third = "third"sv;
+ auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
- 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);
+ 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 289d79d..0fc333f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2174,12 +2174,6 @@
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 @@
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 9f29799..bb5409b 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -41,6 +41,7 @@
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 dc3fa2a..27fa36b 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 @@
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 @@
FLAG_PERSON_BOT,
FLAG_CONTACT_STARRED,
FLAG_DEMOTED,
+ FLAG_NOTIFICATION_SETTING_CHANGED,
})
@Retention(RetentionPolicy.SOURCE)
private @interface ConversationFlags {
@@ -185,6 +188,11 @@
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 @@
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 763e19b..8e1141d 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.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 @@
}
@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 @@
}
PackageData packageData = getPackage(sbn.getPackageName(),
sbn.getUser().getIdentifier());
- if (packageData == null
- || packageData.getConversationStore().getConversation(shortcutId) == null) {
+ if (packageData == null) {
return null;
}
- return packageData.getEventStore().getOrCreateEventHistory(
- EventStore.CATEGORY_SHORTCUT_BASED, shortcutId);
+ ConversationInfo conversationInfo =
+ packageData.getConversationStore().getConversation(shortcutId);
+ if (conversationInfo == null) {
+ return null;
+ }
+ conversationConsumer.accept(conversationInfo);
+ return packageData;
}
@VisibleForTesting
@@ -745,10 +753,19 @@
/** 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 @@
@Override
public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
int reason) {
- if (reason != REASON_CLICK) {
+ 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 = getEventHistoryIfEligible(sbn);
- if (eventHistory == 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 @@
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 @@
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 7a175ca1..2983d58 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 @@
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 @@
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 @@
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 @@
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 3e5c21c..cbe49eb 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 @@
// 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 @@
@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 57039e5..b042e77 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.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.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 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 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 @@
"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 @@
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 @@
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 @@
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 7b3417a..b69cc47 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 @@
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 @@
// 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 @@
// 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 @@
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 @@
// 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 @@
// 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 @@
// 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 0000000..d438a0e
--- /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 70d6cf8..ea8aa6b 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 @@
.setPersonImportant(true)
.setPersonBot(true)
.setContactStarred(true)
+ .setNotificationSettingChanged(true)
.build();
assertEquals(SHORTCUT_ID, conversationInfo.getShortcutId());
@@ -70,6 +71,7 @@
assertTrue(conversationInfo.isPersonImportant());
assertTrue(conversationInfo.isPersonBot());
assertTrue(conversationInfo.isContactStarred());
+ assertTrue(conversationInfo.isNotificationSettingChanged());
}
@Test
@@ -92,6 +94,7 @@
assertFalse(conversationInfo.isPersonImportant());
assertFalse(conversationInfo.isPersonBot());
assertFalse(conversationInfo.isContactStarred());
+ assertFalse(conversationInfo.isNotificationSettingChanged());
}
@Test
@@ -109,6 +112,7 @@
.setPersonImportant(true)
.setPersonBot(true)
.setContactStarred(true)
+ .setNotificationSettingChanged(true)
.build();
ConversationInfo destination = new ConversationInfo.Builder(source)
@@ -128,5 +132,6 @@
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 e16f314..e51ab9db 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.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 @@
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
buildPerson());
+ shortcut.setCached();
mDataManager.addOrUpdateConversationInfo(shortcut);
NotificationListenerService listenerService =
@@ -418,6 +420,68 @@
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 @@
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 69ef499..df92b6e 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.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.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 @@
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 7a5e226..41748b8 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 @@
@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 @@
// 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 @@
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 @@
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 @@
@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 @@
// 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 @@
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 @@
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 @@
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 ac51750..e11392b 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 @@
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 @@
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 @@
}
@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 @@
.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 1debd8c..e3bb1b6 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 @@
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 93ded1b..6c209e4 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 @@
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 @@
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 @@
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 9b7ffd6..e8fab2b 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.RemoteAnimationDefinition;
import android.view.RemoteAnimationTarget;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import org.junit.Test;
@@ -97,7 +96,6 @@
}
@Test
- @FlakyTest(bugId = 131005232)
public void testModeChangeRemoteAnimatorNoSnapshot() {
// setup currently defaults to no snapshot.
setUpOnDisplay(mDisplayContent);
@@ -115,7 +113,6 @@
}
@Test
- @FlakyTest(bugId = 131005232)
public void testCancelPendingChangeOnRemove() {
// setup currently defaults to no snapshot.
setUpOnDisplay(mDisplayContent);
@@ -135,8 +132,7 @@
}
@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 @@
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 0000000..307b40f
--- /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 b6eb901..f831287 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 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 @@
sInsetsModeSession.close();
}
+ @Before
+ public void setup() {
+ mWm.mAnimator.ready();
+ }
+
@Test
public void testControlsForDispatch_regular() {
addWindow(TYPE_STATUS_BAR, "statusBar");
@@ -194,6 +200,7 @@
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 @@
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 @@
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 @@
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 15417d7..2251ee0 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 @@
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 67b1dac..35d1b17 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 @@
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 f6ed314..d7462f8 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 @@
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 af3ec38..dea9294 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 @@
}
}
+ 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 dcc2ff1..60875de 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 @@
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 @@
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 @@
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 a4f1487..520ac19 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 @@
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 f65328d..7d2e880 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 @@
* 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 @@
// 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 @@
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 07a6179..cdf8eb4 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.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 @@
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 b974c56..0983db6 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -2218,15 +2218,23 @@
@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 151fb59..ede67dd 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -49,7 +49,7 @@
*
* 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 @@
/**
* @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 @@
/**
* @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 @@
/**
* @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 @@
/**
* @hide
*/
- @Override
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void getRegistrationTransportType(@NonNull @CallbackExecutor Executor executor,
@NonNull @AccessNetworkConstants.TransportType
@@ -347,8 +346,7 @@
* 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 @@
* 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 @@
* @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 35a6c26..371375c 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 @@
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 482b23f..6927e86 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 @@
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 737b7c7..b0213b0 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -384,7 +384,8 @@
*
* 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 @@
* // etc.
* };
* connectivityManager.requestNetwork(request, networkCallback);
- * }
+ * }</pre>
*
* @return Instance of {@link NetworkSpecifier}.
* @throws IllegalStateException on invalid params set.