Merge "Add CBR and shell to telephony permission"
diff --git a/Android.bp b/Android.bp
index a7ce917..9426a9c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -803,10 +803,9 @@
}
filegroup {
- name: "incremental_data_loader_aidl",
+ name: "dataloader_aidl",
srcs: [
- "core/java/android/service/incremental/IIncrementalDataLoaderStatusListener.aidl",
- "core/java/android/service/incremental/IIncrementalDataLoaderService.aidl",
+ "core/java/android/content/pm/IDataLoaderStatusListener.aidl",
],
path: "core/java",
}
@@ -815,7 +814,27 @@
name: "libincremental_aidl",
srcs: [
":incremental_aidl",
- ":incremental_data_loader_aidl",
+ ],
+ imports: [
+ "libdataloader_aidl",
+ ],
+ backend: {
+ java: {
+ sdk_version: "28",
+ },
+ cpp: {
+ enabled: true,
+ },
+ ndk: {
+ enabled: true,
+ },
+ },
+}
+
+aidl_interface {
+ name: "libdataloader_aidl",
+ srcs: [
+ ":dataloader_aidl",
],
backend: {
java: {
@@ -1675,6 +1694,7 @@
srcs: [
":framework-annotations",
"core/java/android/os/HandlerExecutor.java",
+ "core/java/android/util/BackupUtils.java",
"core/java/android/util/KeyValueListParser.java",
"core/java/android/util/LocalLog.java",
"core/java/android/util/Rational.java",
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java b/apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java
index 5ac922c..3dbb5cf 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java
@@ -24,10 +24,8 @@
import com.google.android.icing.proto.DocumentProto;
import com.google.android.icing.proto.PropertyProto;
+import com.google.android.icing.proto.SearchResultProto;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -94,23 +92,25 @@
* Returns documents containing the given term.
*
* @param term A single exact term to look up in the index.
- * @return The matching documents, or an empty {@code List} if no documents match.
+ * @return A {@link SearchResultProto} containing the matching documents, which may have no
+ * results if no documents match.
*/
@NonNull
- public List<DocumentProto> query(@NonNull String term) {
+ public SearchResultProto query(@NonNull String term) {
String normTerm = normalizeString(term);
Set<Integer> docIds = mIndex.get(normTerm);
if (docIds == null || docIds.isEmpty()) {
- return Collections.emptyList();
+ return SearchResultProto.getDefaultInstance();
}
- List<DocumentProto> matches = new ArrayList<>(docIds.size());
+ SearchResultProto.Builder results = SearchResultProto.newBuilder();
for (int docId : docIds) {
DocumentProto document = mDocStore.get(docId);
if (document != null) {
- matches.add(document);
+ results.addResults(
+ SearchResultProto.ResultProto.newBuilder().setDocument(document));
}
}
- return matches;
+ return results.build();
}
/**
diff --git a/apex/jobscheduler/framework/java/android/os/DeviceIdleManager.java b/apex/jobscheduler/framework/java/android/os/DeviceIdleManager.java
index 8019d4f..4c44334 100644
--- a/apex/jobscheduler/framework/java/android/os/DeviceIdleManager.java
+++ b/apex/jobscheduler/framework/java/android/os/DeviceIdleManager.java
@@ -17,13 +17,10 @@
package android.os;
import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.content.Context;
-import java.util.List;
-
/**
* Access to the service that keeps track of device idleness and drives low power mode based on
* that.
@@ -75,21 +72,6 @@
}
/**
- * Add the specified packages to the power save whitelist.
- *
- * @return the number of packages that were successfully added to the whitelist
- */
- @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
- public int addPowerSaveWhitelistApps(@NonNull List<String> packageNames) {
- try {
- return mService.addPowerSaveWhitelistApps(packageNames);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- return 0;
- }
- }
-
- /**
* Return whether a given package is in the power-save whitelist or not.
* @hide
*/
diff --git a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
index 7a3ed92..4ffcf8a 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
@@ -26,6 +26,8 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
+import java.util.List;
/**
* Interface to access and modify the power save whitelist.
@@ -78,6 +80,31 @@
}
/**
+ * Add the specified package to the power save whitelist.
+ *
+ * @return true if the package was successfully added to the whitelist
+ */
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public boolean addToWhitelist(@NonNull String packageName) {
+ return addToWhitelist(Collections.singletonList(packageName)) == 1;
+ }
+
+ /**
+ * Add the specified packages to the power save whitelist.
+ *
+ * @return the number of packages that were successfully added to the whitelist
+ */
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public int addToWhitelist(@NonNull List<String> packageNames) {
+ try {
+ return mService.addPowerSaveWhitelistApps(packageNames);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ return 0;
+ }
+ }
+
+ /**
* Add an app to the temporary whitelist for a short amount of time.
*
* @param packageName The package to add to the temp whitelist
diff --git a/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java b/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java
index eefb9fa..1072406 100644
--- a/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java
@@ -94,7 +94,7 @@
/**
* Write the persist stats to the specified field.
*/
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
final long flToken = proto.start(JobStorePersistStatsProto.FIRST_LOAD);
diff --git a/apex/jobscheduler/service/java/com/android/server/AnyMotionDetector.java b/apex/jobscheduler/service/java/com/android/server/AnyMotionDetector.java
index 8c5ee7f..316306d 100644
--- a/apex/jobscheduler/service/java/com/android/server/AnyMotionDetector.java
+++ b/apex/jobscheduler/service/java/com/android/server/AnyMotionDetector.java
@@ -231,8 +231,8 @@
Slog.d(TAG, "mCurrentGravityVector = " + currentGravityVectorString);
Slog.d(TAG, "mPreviousGravityVector = " + previousGravityVectorString);
}
- mRunningStats.reset();
status = getStationaryStatus();
+ mRunningStats.reset();
if (DEBUG) Slog.d(TAG, "getStationaryStatus() returned " + status);
if (status != RESULT_UNKNOWN) {
if (mWakeLock.isHeld()) {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 0a4e020..3204013 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -3345,7 +3345,7 @@
mConcurrencyManager.dumpProtoLocked(proto,
JobSchedulerServiceDumpProto.CONCURRENCY_MANAGER, now, nowElapsed);
- mJobs.getPersistStats().writeToProto(proto, JobSchedulerServiceDumpProto.PERSIST_STATS);
+ mJobs.getPersistStats().dumpDebug(proto, JobSchedulerServiceDumpProto.PERSIST_STATS);
}
proto.flush();
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index 7d36303..8eeea1b 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -639,7 +639,7 @@
for (int i = 0; i < mAvailableNetworks.size(); i++) {
Network network = mAvailableNetworks.valueAt(i);
if (network != null) {
- network.writeToProto(proto,
+ network.dumpDebug(proto,
StateControllerProto.ConnectivityController.AVAILABLE_NETWORKS);
}
}
@@ -658,7 +658,7 @@
js.getSourceUid());
NetworkRequest rn = js.getJob().getRequiredNetwork();
if (rn != null) {
- rn.writeToProto(proto,
+ rn.dumpDebug(proto,
StateControllerProto.ConnectivityController.TrackedJob
.REQUIRED_NETWORK);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index c76346f..a8d8bd9 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -1414,7 +1414,7 @@
proto.write(JobStatusDumpProto.JobWorkItem.WORK_ID, work.getWorkId());
proto.write(JobStatusDumpProto.JobWorkItem.DELIVERY_COUNT, work.getDeliveryCount());
if (work.getIntent() != null) {
- work.getIntent().writeToProto(proto, JobStatusDumpProto.JobWorkItem.INTENT);
+ work.getIntent().dumpDebug(proto, JobStatusDumpProto.JobWorkItem.INTENT);
}
Object grants = work.getGrants();
if (grants != null) {
@@ -1683,7 +1683,7 @@
if (full) {
final long jiToken = proto.start(JobStatusDumpProto.JOB_INFO);
- job.getService().writeToProto(proto, JobStatusDumpProto.JobInfo.SERVICE);
+ job.getService().dumpDebug(proto, JobStatusDumpProto.JobInfo.SERVICE);
proto.write(JobStatusDumpProto.JobInfo.IS_PERIODIC, job.isPeriodic());
proto.write(JobStatusDumpProto.JobInfo.PERIOD_INTERVAL_MS, job.getIntervalMillis());
@@ -1722,19 +1722,19 @@
}
}
if (job.getExtras() != null && !job.getExtras().maybeIsEmpty()) {
- job.getExtras().writeToProto(proto, JobStatusDumpProto.JobInfo.EXTRAS);
+ job.getExtras().dumpDebug(proto, JobStatusDumpProto.JobInfo.EXTRAS);
}
if (job.getTransientExtras() != null && !job.getTransientExtras().maybeIsEmpty()) {
- job.getTransientExtras().writeToProto(proto, JobStatusDumpProto.JobInfo.TRANSIENT_EXTRAS);
+ job.getTransientExtras().dumpDebug(proto, JobStatusDumpProto.JobInfo.TRANSIENT_EXTRAS);
}
if (job.getClipData() != null) {
- job.getClipData().writeToProto(proto, JobStatusDumpProto.JobInfo.CLIP_DATA);
+ job.getClipData().dumpDebug(proto, JobStatusDumpProto.JobInfo.CLIP_DATA);
}
if (uriPerms != null) {
uriPerms.dump(proto, JobStatusDumpProto.JobInfo.GRANTED_URI_PERMISSIONS);
}
if (job.getRequiredNetwork() != null) {
- job.getRequiredNetwork().writeToProto(proto, JobStatusDumpProto.JobInfo.REQUIRED_NETWORK);
+ job.getRequiredNetwork().dumpDebug(proto, JobStatusDumpProto.JobInfo.REQUIRED_NETWORK);
}
if (mTotalNetworkDownloadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
proto.write(JobStatusDumpProto.JobInfo.TOTAL_NETWORK_DOWNLOAD_BYTES,
@@ -1822,7 +1822,7 @@
}
if (network != null) {
- network.writeToProto(proto, JobStatusDumpProto.NETWORK);
+ network.dumpDebug(proto, JobStatusDumpProto.NETWORK);
}
if (pendingWork != null) {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index 3fdc571..2e735a4 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -133,7 +133,7 @@
return string(userId, packageName);
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(StateControllerProto.QuotaController.Package.USER_ID, userId);
@@ -1638,7 +1638,7 @@
public void dump(ProtoOutputStream proto, long fieldId, Predicate<JobStatus> predicate) {
final long token = proto.start(fieldId);
- mPkg.writeToProto(proto, StateControllerProto.QuotaController.Timer.PKG);
+ mPkg.dumpDebug(proto, StateControllerProto.QuotaController.Timer.PKG);
proto.write(StateControllerProto.QuotaController.Timer.IS_ACTIVE, isActive());
proto.write(StateControllerProto.QuotaController.Timer.START_TIME_ELAPSED,
mStartTimeElapsed);
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index bcd8be7..2f8b513 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -1171,7 +1171,8 @@
private void fetchCarrierPrivilegedAppsLocked() {
TelephonyManager telephonyManager =
mContext.getSystemService(TelephonyManager.class);
- mCarrierPrivilegedApps = telephonyManager.getPackagesWithCarrierPrivilegesForAllPhones();
+ mCarrierPrivilegedApps =
+ telephonyManager.getCarrierPrivilegedPackagesForAllActiveSubscriptions();
mHaveCarrierPrivilegedApps = true;
if (DEBUG) {
Slog.d(TAG, "apps with carrier privilege " + mCarrierPrivilegedApps);
diff --git a/apex/sdkext/Android.bp b/apex/sdkext/Android.bp
index b8dcb90..40f3c45 100644
--- a/apex/sdkext/Android.bp
+++ b/apex/sdkext/Android.bp
@@ -15,7 +15,13 @@
apex {
name: "com.android.sdkext",
manifest: "manifest.json",
+ binaries: [ "derive_sdk" ],
java_libs: [ "framework-sdkext" ],
+ prebuilts: [
+ "com.android.sdkext.ldconfig",
+ "cur_sdkinfo",
+ "derive_sdk.rc",
+ ],
key: "com.android.sdkext.key",
certificate: ":com.android.sdkext.certificate",
}
@@ -30,3 +36,35 @@
name: "com.android.sdkext.certificate",
certificate: "com.android.sdkext",
}
+
+prebuilt_etc {
+ name: "com.android.sdkext.ldconfig",
+ src: "ld.config.txt",
+ filename: "ld.config.txt",
+ installable: false,
+}
+
+python_binary_host {
+ name: "gen_sdkinfo",
+ srcs: [
+ "derive_sdk/sdk.proto",
+ "gen_sdkinfo.py",
+ ],
+ proto: {
+ canonical_path_from_root: false,
+ },
+}
+
+gensrcs {
+ name: "cur_sdkinfo_src",
+ srcs: [""],
+ tools: [ "gen_sdkinfo" ],
+ cmd: "$(location) -v 0 -o $(out)",
+}
+
+prebuilt_etc {
+ name: "cur_sdkinfo",
+ src: ":cur_sdkinfo_src",
+ filename: "sdkinfo.binarypb",
+ installable: false,
+}
diff --git a/apex/sdkext/derive_sdk/Android.bp b/apex/sdkext/derive_sdk/Android.bp
new file mode 100644
index 0000000..c4e3c29
--- /dev/null
+++ b/apex/sdkext/derive_sdk/Android.bp
@@ -0,0 +1,37 @@
+// 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.
+
+cc_binary {
+ name: "derive_sdk",
+ srcs: [
+ "derive_sdk.cpp",
+ "sdk.proto",
+ ],
+ proto: {
+ type: "lite",
+ },
+ sdk_version: "current",
+ stl: "c++_static",
+ shared_libs: [ "liblog" ],
+ static_libs: [
+ "libbase_ndk",
+ "libprotobuf-cpp-lite-ndk",
+ ],
+}
+
+prebuilt_etc {
+ name: "derive_sdk.rc",
+ src: "derive_sdk.rc",
+ installable: false,
+}
diff --git a/apex/sdkext/derive_sdk/derive_sdk.cpp b/apex/sdkext/derive_sdk/derive_sdk.cpp
new file mode 100644
index 0000000..0aacebe
--- /dev/null
+++ b/apex/sdkext/derive_sdk/derive_sdk.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "derive_sdk"
+
+#include <algorithm>
+#include <dirent.h>
+#include <iostream>
+#include <sys/stat.h>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+
+#include "frameworks/base/apex/sdkext/derive_sdk/sdk.pb.h"
+
+using com::android::sdkext::proto::SdkVersion;
+
+int main(int, char**) {
+ std::unique_ptr<DIR, decltype(&closedir)> apex(opendir("/apex"), closedir);
+ if (!apex) {
+ LOG(ERROR) << "Could not read /apex";
+ return EXIT_FAILURE;
+ }
+ struct dirent* de;
+ std::vector<std::string> paths;
+ while ((de = readdir(apex.get()))) {
+ std::string name = de->d_name;
+ if (name[0] == '.' || name.find('@') != std::string::npos) {
+ // Skip <name>@<ver> dirs, as they are bind-mounted to <name>
+ continue;
+ }
+ std::string path = "/apex/" + name + "/etc/sdkinfo.binarypb";
+ struct stat statbuf;
+ if (stat(path.c_str(), &statbuf) == 0) {
+ paths.push_back(path);
+ }
+ }
+
+ std::vector<int> versions;
+ for (const auto& path : paths) {
+ std::string contents;
+ if (!android::base::ReadFileToString(path, &contents, true)) {
+ LOG(ERROR) << "failed to read " << path;
+ continue;
+ }
+ SdkVersion sdk_version;
+ if (!sdk_version.ParseFromString(contents)) {
+ LOG(ERROR) << "failed to parse " << path;
+ continue;
+ }
+ versions.push_back(sdk_version.version());
+ }
+ auto itr = std::min_element(versions.begin(), versions.end());
+ std::string prop_value = itr == versions.end() ? "0" : std::to_string(*itr);
+
+ if (!android::base::SetProperty("persist.com.android.sdkext.sdk_info", prop_value)) {
+ LOG(ERROR) << "failed to set sdk_info prop";
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/apex/sdkext/derive_sdk/derive_sdk.rc b/apex/sdkext/derive_sdk/derive_sdk.rc
new file mode 100644
index 0000000..1b66794
--- /dev/null
+++ b/apex/sdkext/derive_sdk/derive_sdk.rc
@@ -0,0 +1,3 @@
+service derive_sdk /apex/com.android.sdkext/bin/derive_sdk
+ oneshot
+ disabled
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/apex/sdkext/derive_sdk/sdk.proto
similarity index 63%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to apex/sdkext/derive_sdk/sdk.proto
index 007ec94..d15b935 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/apex/sdkext/derive_sdk/sdk.proto
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,12 @@
* limitations under the License.
*/
-package android.net.wifi;
+syntax = "proto3";
+package com.android.sdkext.proto;
-parcelable WifiActivityEnergyInfo;
+option java_outer_classname = "SdkProto";
+option optimize_for = LITE_RUNTIME;
+
+message SdkVersion {
+ int32 version = 1;
+}
diff --git a/apex/sdkext/gen_sdkinfo.py b/apex/sdkext/gen_sdkinfo.py
new file mode 100644
index 0000000..5af478b
--- /dev/null
+++ b/apex/sdkext/gen_sdkinfo.py
@@ -0,0 +1,19 @@
+import sdk_pb2
+import sys
+
+if __name__ == '__main__':
+ argv = sys.argv[1:]
+ if not len(argv) == 4 or sorted([argv[0], argv[2]]) != ['-o', '-v']:
+ print('usage: gen_sdkinfo -v <version> -o <output-file>')
+ sys.exit(1)
+
+ for i in range(len(argv)):
+ if sys.argv[i] == '-o':
+ filename = sys.argv[i+1]
+ if sys.argv[i] == '-v':
+ version = int(sys.argv[i+1])
+
+ proto = sdk_pb2.SdkVersion()
+ proto.version = version
+ with open(filename, 'wb') as f:
+ f.write(proto.SerializeToString())
diff --git a/apex/sdkext/ld.config.txt b/apex/sdkext/ld.config.txt
new file mode 100644
index 0000000..b447068
--- /dev/null
+++ b/apex/sdkext/ld.config.txt
@@ -0,0 +1,31 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Bionic loader config file for the sdkext apex.
+
+dir.sdkext = /apex/com.android.sdkext/bin/
+
+[sdkext]
+additional.namespaces = platform
+
+namespace.default.isolated = true
+namespace.default.links = platform
+namespace.default.link.platform.allow_all_shared_libs = true
+
+###############################################################################
+# "platform" namespace: used for NDK libraries
+###############################################################################
+namespace.platform.isolated = true
+namespace.platform.search.paths = /system/${LIB}
+namespace.platform.asan.search.paths = /data/asan/system/${LIB}
+
+# /system/lib/libc.so, etc are symlinks to /apex/com.android.lib/lib/bionic/libc.so, etc.
+# Add /apex/... path to the permitted paths because linker uses realpath(3)
+# to check the accessibility of the lib. We could add this to search.paths
+# instead but that makes the resolution of bionic libs be dependent on
+# the order of /system/lib and /apex/... in search.paths. If /apex/...
+# is after /system/lib, then /apex/... is never tried because libc.so
+# is always found in /system/lib but fails to pass the accessibility test
+# because of its realpath. It's better to not depend on the ordering if
+# possible.
+namespace.platform.permitted.paths = /apex/com.android.runtime/${LIB}/bionic
+namespace.platform.asan.permitted.paths = /apex/com.android.runtime/${LIB}/bionic
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
index f11d4f8..c9139b1 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
@@ -64,8 +64,7 @@
import android.net.Network;
import android.net.NetworkRequest;
import android.net.NetworkStats;
-import android.net.wifi.IWifiManager;
-import android.net.wifi.WifiActivityEnergyInfo;
+import android.net.wifi.WifiManager;
import android.os.BatteryStats;
import android.os.BatteryStatsInternal;
import android.os.Binder;
@@ -98,6 +97,7 @@
import android.os.Temperature;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.connectivity.WifiActivityEnergyInfo;
import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
@@ -170,6 +170,7 @@
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -342,7 +343,7 @@
private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
- private IWifiManager mWifiManager = null;
+ private WifiManager mWifiManager = null;
private TelephonyManager mTelephony = null;
@GuardedBy("sStatsdLock")
private final HashSet<Long> mDeathTimeMillis = new HashSet<>();
@@ -1148,35 +1149,48 @@
private void pullWifiActivityInfo(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
- long token = Binder.clearCallingIdentity();
+ WifiManager wifiManager;
synchronized (this) {
if (mWifiManager == null) {
- mWifiManager =
- IWifiManager.Stub.asInterface(
- ServiceManager.getService(Context.WIFI_SERVICE));
+ mWifiManager = mContext.getSystemService(WifiManager.class);
}
+ wifiManager = mWifiManager;
}
- if (mWifiManager != null) {
- try {
- SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi");
- mWifiManager.requestActivityInfo(wifiReceiver);
- final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
- wallClockNanos);
- e.writeLong(wifiInfo.getTimeSinceBootMillis());
- e.writeInt(wifiInfo.getStackState());
- e.writeLong(wifiInfo.getControllerTxDurationMillis());
- e.writeLong(wifiInfo.getControllerRxDurationMillis());
- e.writeLong(wifiInfo.getControllerIdleDurationMillis());
- e.writeLong(wifiInfo.getControllerEnergyUsedMicroJoules());
- pulledData.add(e);
- } catch (RemoteException e) {
- Slog.e(TAG,
- "Pulling wifiManager for wifi controller activity energy info has error",
- e);
- } finally {
- Binder.restoreCallingIdentity(token);
+ if (wifiManager == null) {
+ return;
+ }
+ long token = Binder.clearCallingIdentity();
+ try {
+ SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi");
+ wifiManager.getWifiActivityEnergyInfoAsync(
+ new Executor() {
+ @Override
+ public void execute(Runnable runnable) {
+ // run the listener on the binder thread, if it was run on the main
+ // thread it would deadlock since we would be waiting on ourselves
+ runnable.run();
+ }
+ },
+ info -> {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, info);
+ wifiReceiver.send(0, bundle);
+ }
+ );
+ final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
+ if (wifiInfo == null) {
+ return;
}
+ StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+ e.writeLong(wifiInfo.getTimeSinceBootMillis());
+ e.writeInt(wifiInfo.getStackState());
+ e.writeLong(wifiInfo.getControllerTxDurationMillis());
+ e.writeLong(wifiInfo.getControllerRxDurationMillis());
+ e.writeLong(wifiInfo.getControllerIdleDurationMillis());
+ e.writeLong(wifiInfo.getControllerEnergyUsedMicroJoules());
+ pulledData.add(e);
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
@@ -1796,7 +1810,7 @@
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
wallClockNanos);
ProtoOutputStream proto = new ProtoOutputStream();
- powerProfile.writeToProto(proto);
+ powerProfile.dumpDebug(proto);
proto.flush();
e.writeStorage(proto.getBytes());
pulledData.add(e);
diff --git a/api/current.txt b/api/current.txt
index 884bc5a..3cf158d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -299,6 +299,7 @@
field public static final int animateFirstView = 16843477; // 0x10102d5
field public static final int animateLayoutChanges = 16843506; // 0x10102f2
field public static final int animateOnClick = 16843356; // 0x101025c
+ field public static final int animatedImageDrawable = 16844298; // 0x101060a
field public static final int animation = 16843213; // 0x10101cd
field public static final int animationCache = 16842989; // 0x10100ed
field public static final int animationDuration = 16843026; // 0x1010112
@@ -723,6 +724,7 @@
field public static final int host = 16842792; // 0x1010028
field public static final int hotSpotX = 16844055; // 0x1010517
field public static final int hotSpotY = 16844056; // 0x1010518
+ field public static final int htmlDescription = 16844299; // 0x101060b
field public static final int hyphenationFrequency = 16843998; // 0x10104de
field public static final int icon = 16842754; // 0x1010002
field @Deprecated public static final int iconPreview = 16843337; // 0x1010249
@@ -2926,6 +2928,7 @@
method public int describeContents();
method public static String feedbackTypeToString(int);
method public static String flagToString(int);
+ method public int getAnimatedImageRes();
method @Deprecated public boolean getCanRetrieveWindowContent();
method public int getCapabilities();
method @Deprecated public String getDescription();
@@ -2935,6 +2938,7 @@
method public android.content.pm.ResolveInfo getResolveInfo();
method public String getSettingsActivityName();
method public String loadDescription(android.content.pm.PackageManager);
+ method @Nullable public String loadHtmlDescription(@NonNull android.content.pm.PackageManager);
method public CharSequence loadSummary(android.content.pm.PackageManager);
method public void setInteractiveUiTimeoutMillis(@IntRange(from=0) int);
method public void setNonInteractiveUiTimeoutMillis(@IntRange(from=0) int);
@@ -5177,12 +5181,12 @@
method public android.content.Intent getResultData();
}
- public abstract class IntentService extends android.app.Service {
- ctor public IntentService(String);
- method @Nullable public android.os.IBinder onBind(android.content.Intent);
- method @WorkerThread protected abstract void onHandleIntent(@Nullable android.content.Intent);
- method public void onStart(@Nullable android.content.Intent, int);
- method public void setIntentRedelivery(boolean);
+ @Deprecated public abstract class IntentService extends android.app.Service {
+ ctor @Deprecated public IntentService(String);
+ method @Deprecated @Nullable public android.os.IBinder onBind(android.content.Intent);
+ method @Deprecated @WorkerThread protected abstract void onHandleIntent(@Nullable android.content.Intent);
+ method @Deprecated public void onStart(@Nullable android.content.Intent, int);
+ method @Deprecated public void setIntentRedelivery(boolean);
}
public class KeyguardManager {
@@ -11361,6 +11365,15 @@
field public int version;
}
+ public final class InstallSourceInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public String getInitiatingPackageName();
+ method @Nullable public String getInstallingPackageName();
+ method @Nullable public String getOriginatingPackageName();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.InstallSourceInfo> CREATOR;
+ }
+
public class InstrumentationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
ctor public InstrumentationInfo();
ctor public InstrumentationInfo(android.content.pm.InstrumentationInfo);
@@ -11725,10 +11738,11 @@
method public abstract int getComponentEnabledSetting(@NonNull android.content.ComponentName);
method @NonNull public abstract android.graphics.drawable.Drawable getDefaultActivityIcon();
method @Nullable public abstract android.graphics.drawable.Drawable getDrawable(@NonNull String, @DrawableRes int, @Nullable android.content.pm.ApplicationInfo);
+ method @NonNull public android.content.pm.InstallSourceInfo getInstallSourceInfo(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int);
method @NonNull public java.util.List<android.content.pm.ModuleInfo> getInstalledModules(int);
method @NonNull public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
- method @Nullable public abstract String getInstallerPackageName(@NonNull String);
+ method @Deprecated @Nullable public abstract String getInstallerPackageName(@NonNull String);
method @NonNull public abstract byte[] getInstantAppCookie();
method public abstract int getInstantAppCookieMaxBytes();
method @NonNull public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -23780,6 +23794,7 @@
method public int getSampleRate();
method public int getState();
method public int getTimestamp(@NonNull android.media.AudioTimestamp, int);
+ method public boolean isPrivacySensitive();
method public int read(@NonNull byte[], int, int);
method public int read(@NonNull byte[], int, int, int);
method public int read(@NonNull short[], int, int);
@@ -23822,6 +23837,7 @@
method @NonNull public android.media.AudioRecord.Builder setAudioPlaybackCaptureConfig(@NonNull android.media.AudioPlaybackCaptureConfiguration);
method public android.media.AudioRecord.Builder setAudioSource(int) throws java.lang.IllegalArgumentException;
method public android.media.AudioRecord.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException;
+ method @NonNull public android.media.AudioRecord.Builder setPrivacySensitive(boolean);
}
public static final class AudioRecord.MetricsConstants {
@@ -25601,6 +25617,50 @@
field public static final int MUXER_OUTPUT_WEBM = 1; // 0x1
}
+ public final class MediaParser {
+ method public boolean advance(@NonNull android.media.MediaParser.SeekableInputReader) throws java.io.IOException, java.lang.InterruptedException;
+ method @NonNull public static android.media.MediaParser create(@NonNull android.media.MediaParser.OutputConsumer, @NonNull java.lang.String...);
+ method @NonNull public static android.media.MediaParser createByName(@NonNull String, @NonNull android.media.MediaParser.OutputConsumer);
+ method @Nullable public String getExtractorName();
+ method @NonNull public static java.util.List<java.lang.String> getExtractorNames(@NonNull android.media.MediaFormat);
+ method public void release();
+ method public void seek(@NonNull android.media.MediaParser.SeekPoint);
+ }
+
+ public static interface MediaParser.InputReader {
+ method public long getLength();
+ method public long getPosition();
+ method public int read(@NonNull byte[], int, int) throws java.io.IOException, java.lang.InterruptedException;
+ }
+
+ public static interface MediaParser.OutputConsumer {
+ method public void onFormat(int, @NonNull android.media.MediaFormat);
+ method public void onSampleCompleted(int, long, int, int, int, @Nullable android.media.MediaCodec.CryptoInfo);
+ method public void onSampleData(int, @NonNull android.media.MediaParser.InputReader) throws java.io.IOException, java.lang.InterruptedException;
+ method public void onSeekMap(@NonNull android.media.MediaParser.SeekMap);
+ method public void onTracksFound(int);
+ }
+
+ public static interface MediaParser.SeekMap {
+ method public long getDurationUs();
+ method @NonNull public android.util.Pair<android.media.MediaParser.SeekPoint,android.media.MediaParser.SeekPoint> getSeekPoints(long);
+ method public boolean isSeekable();
+ field public static final int UNKNOWN_DURATION = -2147483648; // 0x80000000
+ }
+
+ public static final class MediaParser.SeekPoint {
+ field @NonNull public static final android.media.MediaParser.SeekPoint START;
+ field public final long position;
+ field public final long timeUs;
+ }
+
+ public static interface MediaParser.SeekableInputReader extends android.media.MediaParser.InputReader {
+ method public void seekToPosition(long);
+ }
+
+ public static final class MediaParser.UnrecognizedInputFormatException extends java.io.IOException {
+ }
+
public class MediaPlayer implements android.media.AudioRouting android.media.VolumeAutomation {
ctor public MediaPlayer();
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
@@ -25841,6 +25901,7 @@
method public android.media.AudioDeviceInfo getPreferredDevice();
method public android.media.AudioDeviceInfo getRoutedDevice();
method public android.view.Surface getSurface();
+ method public boolean isPrivacySensitive();
method public void pause() throws java.lang.IllegalStateException;
method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
method public void registerAudioRecordingCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioRecordingCallback);
@@ -25872,6 +25933,7 @@
method public boolean setPreferredMicrophoneDirection(int);
method public boolean setPreferredMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float);
method public void setPreviewDisplay(android.view.Surface);
+ method public void setPrivacySensitive(boolean);
method public void setProfile(android.media.CamcorderProfile);
method public void setVideoEncoder(int) throws java.lang.IllegalStateException;
method public void setVideoEncodingBitRate(int);
@@ -29265,12 +29327,14 @@
method public static long getMobileRxPackets();
method public static long getMobileTxBytes();
method public static long getMobileTxPackets();
+ method public static long getRxPackets(@NonNull String);
method public static int getThreadStatsTag();
method public static int getThreadStatsUid();
method public static long getTotalRxBytes();
method public static long getTotalRxPackets();
method public static long getTotalTxBytes();
method public static long getTotalTxPackets();
+ method public static long getTxPackets(@NonNull String);
method public static long getUidRxBytes(int);
method public static long getUidRxPackets(int);
method @Deprecated public static long getUidTcpRxBytes(int);
@@ -36874,6 +36938,7 @@
method @WorkerThread public static boolean isBlocked(android.content.Context, String);
method @WorkerThread public static int unblock(android.content.Context, String);
field public static final String AUTHORITY = "com.android.blockednumber";
+ field public static final android.net.Uri AUTHORITY_URI;
}
public static class BlockedNumberContract.BlockedNumbers {
@@ -38613,15 +38678,13 @@
ctor public MediaStore();
method @Nullable public static android.net.Uri getDocumentUri(@NonNull android.content.Context, @NonNull android.net.Uri);
method @NonNull public static java.util.Set<java.lang.String> getExternalVolumeNames(@NonNull android.content.Context);
- method public static boolean getIncludePending(@NonNull android.net.Uri);
method public static android.net.Uri getMediaScannerUri();
method @Nullable public static android.net.Uri getMediaUri(@NonNull android.content.Context, @NonNull android.net.Uri);
method public static boolean getRequireOriginal(@NonNull android.net.Uri);
method @NonNull public static String getVersion(@NonNull android.content.Context);
method @NonNull public static String getVersion(@NonNull android.content.Context, @NonNull String);
method @NonNull public static String getVolumeName(@NonNull android.net.Uri);
- method @NonNull public static android.net.Uri setIncludePending(@NonNull android.net.Uri);
- method @NonNull public static android.net.Uri setIncludeTrashed(@NonNull android.net.Uri);
+ method @Deprecated @NonNull public static android.net.Uri setIncludePending(@NonNull android.net.Uri);
method @NonNull public static android.net.Uri setRequireOriginal(@NonNull android.net.Uri);
method public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri);
method public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri, long);
@@ -38657,9 +38720,17 @@
field public static final String INTENT_ACTION_TEXT_OPEN_FROM_SEARCH = "android.media.action.TEXT_OPEN_FROM_SEARCH";
field public static final String INTENT_ACTION_VIDEO_CAMERA = "android.media.action.VIDEO_CAMERA";
field public static final String INTENT_ACTION_VIDEO_PLAY_FROM_SEARCH = "android.media.action.VIDEO_PLAY_FROM_SEARCH";
+ field public static final int MATCH_DEFAULT = 0; // 0x0
+ field public static final int MATCH_EXCLUDE = 2; // 0x2
+ field public static final int MATCH_INCLUDE = 1; // 0x1
+ field public static final int MATCH_ONLY = 3; // 0x3
field public static final String MEDIA_IGNORE_FILENAME = ".nomedia";
field public static final String MEDIA_SCANNER_VOLUME = "volume";
field public static final String META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE = "android.media.still_image_camera_preview_service";
+ field public static final String QUERY_ARG_MATCH_FAVORITE = "android:query-arg-match-favorite";
+ field public static final String QUERY_ARG_MATCH_PENDING = "android:query-arg-match-pending";
+ field public static final String QUERY_ARG_MATCH_TRASHED = "android:query-arg-match-trashed";
+ field public static final String QUERY_ARG_RELATED_URI = "android:query-arg-related-uri";
field public static final String UNKNOWN_STRING = "<unknown>";
field public static final String VOLUME_EXTERNAL = "external";
field public static final String VOLUME_EXTERNAL_PRIMARY = "external_primary";
@@ -43072,6 +43143,7 @@
field public static final int MS_INVALIDATE;
field public static final int MS_SYNC;
field public static final int NETLINK_INET_DIAG;
+ field public static final int NETLINK_NETFILTER;
field public static final int NETLINK_ROUTE;
field public static final int NI_DGRAM;
field public static final int NI_NAMEREQD;
@@ -43482,6 +43554,7 @@
method public int getCallProperties();
method public String getCallerDisplayName();
method public int getCallerDisplayNamePresentation();
+ method public int getCallerNumberVerificationStatus();
method public final long getConnectTimeMillis();
method public long getCreationTimeMillis();
method public android.telecom.DisconnectCause getDisconnectCause();
@@ -43663,6 +43736,7 @@
method public final android.telecom.CallAudioState getCallAudioState();
method public final String getCallerDisplayName();
method public final int getCallerDisplayNamePresentation();
+ method public int getCallerNumberVerificationStatus();
method public final android.telecom.Conference getConference();
method public final java.util.List<android.telecom.Conferenceable> getConferenceables();
method public final int getConnectionCapabilities();
@@ -43714,6 +43788,7 @@
method public final void setAudioModeIsVoip(boolean);
method public final void setAudioRoute(int);
method public final void setCallerDisplayName(String, int);
+ method public void setCallerNumberVerificationStatus(int);
method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
method public final void setConferenceables(java.util.List<android.telecom.Conferenceable>);
method public final void setConnectionCapabilities(int);
@@ -43733,6 +43808,27 @@
method public final void setVideoProvider(android.telecom.Connection.VideoProvider);
method public final void setVideoState(int);
method public static String stateToString(int);
+ field public static final int AUDIO_CODEC_AMR = 1; // 0x1
+ field public static final int AUDIO_CODEC_AMR_WB = 2; // 0x2
+ field public static final int AUDIO_CODEC_EVRC = 4; // 0x4
+ field public static final int AUDIO_CODEC_EVRC_B = 5; // 0x5
+ field public static final int AUDIO_CODEC_EVRC_NW = 7; // 0x7
+ field public static final int AUDIO_CODEC_EVRC_WB = 6; // 0x6
+ field public static final int AUDIO_CODEC_EVS_FB = 20; // 0x14
+ field public static final int AUDIO_CODEC_EVS_NB = 17; // 0x11
+ field public static final int AUDIO_CODEC_EVS_SWB = 19; // 0x13
+ field public static final int AUDIO_CODEC_EVS_WB = 18; // 0x12
+ field public static final int AUDIO_CODEC_G711A = 13; // 0xd
+ field public static final int AUDIO_CODEC_G711AB = 15; // 0xf
+ field public static final int AUDIO_CODEC_G711U = 11; // 0xb
+ field public static final int AUDIO_CODEC_G722 = 14; // 0xe
+ field public static final int AUDIO_CODEC_G723 = 12; // 0xc
+ field public static final int AUDIO_CODEC_G729 = 16; // 0x10
+ field public static final int AUDIO_CODEC_GSM_EFR = 8; // 0x8
+ field public static final int AUDIO_CODEC_GSM_FR = 9; // 0x9
+ field public static final int AUDIO_CODEC_GSM_HR = 10; // 0xa
+ field public static final int AUDIO_CODEC_NONE = 0; // 0x0
+ field public static final int AUDIO_CODEC_QCELP13K = 3; // 0x3
field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000
@@ -43766,6 +43862,7 @@
field public static final String EVENT_RTT_AUDIO_INDICATION_CHANGED = "android.telecom.event.RTT_AUDIO_INDICATION_CHANGED";
field public static final String EXTRA_ANSWERING_DROPS_FG_CALL = "android.telecom.extra.ANSWERING_DROPS_FG_CALL";
field public static final String EXTRA_ANSWERING_DROPS_FG_CALL_APP_NAME = "android.telecom.extra.ANSWERING_DROPS_FG_CALL_APP_NAME";
+ field public static final String EXTRA_AUDIO_CODEC = "android.telecom.extra.AUDIO_CODEC";
field public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
field public static final String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
field public static final String EXTRA_IS_RTT_AUDIO_PRESENT = "android.telecom.extra.IS_RTT_AUDIO_PRESENT";
@@ -43787,6 +43884,9 @@
field public static final int STATE_NEW = 1; // 0x1
field public static final int STATE_PULLING_CALL = 7; // 0x7
field public static final int STATE_RINGING = 2; // 0x2
+ field public static final int VERIFICATION_STATUS_FAILED = 2; // 0x2
+ field public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0; // 0x0
+ field public static final int VERIFICATION_STATUS_PASSED = 1; // 0x1
}
public static final class Connection.RttModifyStatus {
@@ -44534,6 +44634,7 @@
field public static final String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
field public static final String KEY_DIAL_STRING_REPLACE_STRING_ARRAY = "dial_string_replace_string_array";
field public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
+ field public static final String KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL = "disable_supplementary_services_in_airplane_mode_bool";
field public static final String KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY = "disconnect_cause_play_busytone_int_array";
field public static final String KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL = "display_hd_audio_property_bool";
field public static final String KEY_DROP_VIDEO_CALL_WHEN_ANSWERING_AUDIO_CALL_BOOL = "drop_video_call_when_answering_audio_call_bool";
diff --git a/api/removed.txt b/api/removed.txt
index e0e26f7..1a2f434 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -438,7 +438,9 @@
public final class MediaStore {
method @Deprecated @NonNull public static android.net.Uri createPending(@NonNull android.content.Context, @NonNull android.provider.MediaStore.PendingParams);
method @Deprecated @NonNull public static java.util.Set<java.lang.String> getAllVolumeNames(@NonNull android.content.Context);
+ method @Deprecated public static boolean getIncludePending(@NonNull android.net.Uri);
method @Deprecated @NonNull public static android.provider.MediaStore.PendingSession openPending(@NonNull android.content.Context, @NonNull android.net.Uri);
+ method @Deprecated @NonNull public static android.net.Uri setIncludeTrashed(@NonNull android.net.Uri);
}
public static interface MediaStore.Audio.AudioColumns extends android.provider.MediaStore.MediaColumns {
diff --git a/api/system-current.txt b/api/system-current.txt
index fb7ec01..c7bde93 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1399,6 +1399,7 @@
public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean connect(android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean disconnect(android.bluetooth.BluetoothDevice);
+ method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothDevice getActiveDevice();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPriority(android.bluetooth.BluetoothDevice, int);
@@ -1433,6 +1434,37 @@
field @Deprecated public static final int PRIORITY_ON = 100; // 0x64
}
+ public final class BluetoothUuid {
+ method public static boolean containsAnyUuid(@Nullable android.os.ParcelUuid[], @Nullable android.os.ParcelUuid[]);
+ method @NonNull public static android.os.ParcelUuid parseUuidFrom(@Nullable byte[]);
+ field @NonNull public static final android.os.ParcelUuid A2DP_SINK;
+ field @NonNull public static final android.os.ParcelUuid A2DP_SOURCE;
+ field @NonNull public static final android.os.ParcelUuid ADV_AUDIO_DIST;
+ field @NonNull public static final android.os.ParcelUuid AVRCP_CONTROLLER;
+ field @NonNull public static final android.os.ParcelUuid AVRCP_TARGET;
+ field @NonNull public static final android.os.ParcelUuid BASE_UUID;
+ field @NonNull public static final android.os.ParcelUuid BNEP;
+ field @NonNull public static final android.os.ParcelUuid HEARING_AID;
+ field @NonNull public static final android.os.ParcelUuid HFP;
+ field @NonNull public static final android.os.ParcelUuid HFP_AG;
+ field @NonNull public static final android.os.ParcelUuid HID;
+ field @NonNull public static final android.os.ParcelUuid HOGP;
+ field @NonNull public static final android.os.ParcelUuid HSP;
+ field @NonNull public static final android.os.ParcelUuid HSP_AG;
+ field @NonNull public static final android.os.ParcelUuid MAP;
+ field @NonNull public static final android.os.ParcelUuid MAS;
+ field @NonNull public static final android.os.ParcelUuid MNS;
+ field @NonNull public static final android.os.ParcelUuid NAP;
+ field @NonNull public static final android.os.ParcelUuid OBEX_OBJECT_PUSH;
+ field @NonNull public static final android.os.ParcelUuid PANU;
+ field @NonNull public static final android.os.ParcelUuid PBAP_PCE;
+ field @NonNull public static final android.os.ParcelUuid PBAP_PSE;
+ field @NonNull public static final android.os.ParcelUuid SAP;
+ field public static final int UUID_BYTES_128_BIT = 16; // 0x10
+ field public static final int UUID_BYTES_16_BIT = 2; // 0x2
+ field public static final int UUID_BYTES_32_BIT = 4; // 0x4
+ }
+
}
package android.bluetooth.le {
@@ -4488,6 +4520,7 @@
public class Network implements android.os.Parcelable {
ctor public Network(@NonNull android.net.Network);
method @NonNull public android.net.Network getPrivateDnsBypassingCopy();
+ field public final int netId;
}
public final class NetworkCapabilities implements android.os.Parcelable {
@@ -4732,7 +4765,7 @@
method @NonNull public java.util.List<android.net.ipsec.ike.IkeTrafficSelector> getOutboundTrafficSelectors();
}
- public abstract class ChildSessionOptions {
+ public abstract class ChildSessionParams {
}
public class IkeFqdnIdentification extends android.net.ipsec.ike.IkeIdentification {
@@ -4777,11 +4810,11 @@
}
public final class IkeSession implements java.lang.AutoCloseable {
- ctor public IkeSession(@NonNull android.content.Context, @NonNull android.net.ipsec.ike.IkeSessionOptions, @NonNull android.net.ipsec.ike.ChildSessionOptions, @NonNull java.util.concurrent.Executor, @NonNull android.net.ipsec.ike.IkeSessionCallback, @NonNull android.net.ipsec.ike.ChildSessionCallback);
+ ctor public IkeSession(@NonNull android.content.Context, @NonNull android.net.ipsec.ike.IkeSessionParams, @NonNull android.net.ipsec.ike.ChildSessionParams, @NonNull java.util.concurrent.Executor, @NonNull android.net.ipsec.ike.IkeSessionCallback, @NonNull android.net.ipsec.ike.ChildSessionCallback);
method public void close();
method public void closeChildSession(@NonNull android.net.ipsec.ike.ChildSessionCallback);
method public void kill();
- method public void openChildSession(@NonNull android.net.ipsec.ike.ChildSessionOptions, @NonNull android.net.ipsec.ike.ChildSessionCallback);
+ method public void openChildSession(@NonNull android.net.ipsec.ike.ChildSessionParams, @NonNull android.net.ipsec.ike.ChildSessionCallback);
}
public interface IkeSessionCallback {
@@ -4799,21 +4832,21 @@
field public static final int EXTENSION_TYPE_MOBIKE = 2; // 0x2
}
- public final class IkeSessionOptions {
+ public final class IkeSessionParams {
}
- public static final class IkeSessionOptions.Builder {
- ctor public IkeSessionOptions.Builder();
- method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder addSaProposal(@NonNull android.net.ipsec.ike.IkeSaProposal);
- method @NonNull public android.net.ipsec.ike.IkeSessionOptions build();
- method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setAuthDigitalSignature(@NonNull java.security.cert.X509Certificate, @NonNull java.security.cert.X509Certificate, @NonNull java.security.PrivateKey);
- method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setAuthDigitalSignature(@NonNull java.security.cert.X509Certificate, @NonNull java.security.cert.X509Certificate, @NonNull java.util.List<java.security.cert.X509Certificate>, @NonNull java.security.PrivateKey);
- method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setAuthEap(@NonNull java.security.cert.X509Certificate, @NonNull android.net.eap.EapSessionConfig);
- method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setAuthPsk(@NonNull byte[]);
- method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setLocalIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
- method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setRemoteIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
- method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setServerAddress(@NonNull java.net.InetAddress);
- method @NonNull public android.net.ipsec.ike.IkeSessionOptions.Builder setUdpEncapsulationSocket(@NonNull android.net.IpSecManager.UdpEncapsulationSocket);
+ public static final class IkeSessionParams.Builder {
+ ctor public IkeSessionParams.Builder();
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder addSaProposal(@NonNull android.net.ipsec.ike.IkeSaProposal);
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams build();
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthDigitalSignature(@NonNull java.security.cert.X509Certificate, @NonNull java.security.cert.X509Certificate, @NonNull java.security.PrivateKey);
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthDigitalSignature(@NonNull java.security.cert.X509Certificate, @NonNull java.security.cert.X509Certificate, @NonNull java.util.List<java.security.cert.X509Certificate>, @NonNull java.security.PrivateKey);
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthEap(@NonNull java.security.cert.X509Certificate, @NonNull android.net.eap.EapSessionConfig);
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthPsk(@NonNull byte[]);
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setLocalIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setRemoteIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setServerAddress(@NonNull java.net.InetAddress);
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setUdpEncapsulationSocket(@NonNull android.net.IpSecManager.UdpEncapsulationSocket);
}
public final class IkeTrafficSelector {
@@ -4850,33 +4883,33 @@
field public static final int PSEUDORANDOM_FUNCTION_HMAC_SHA1 = 2; // 0x2
}
- public final class TransportModeChildSessionOptions extends android.net.ipsec.ike.ChildSessionOptions {
+ public final class TransportModeChildSessionParams extends android.net.ipsec.ike.ChildSessionParams {
}
- public static final class TransportModeChildSessionOptions.Builder {
- ctor public TransportModeChildSessionOptions.Builder();
- method @NonNull public android.net.ipsec.ike.TransportModeChildSessionOptions.Builder addInboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
- method @NonNull public android.net.ipsec.ike.TransportModeChildSessionOptions.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
- method @NonNull public android.net.ipsec.ike.TransportModeChildSessionOptions.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
- method @NonNull public android.net.ipsec.ike.TransportModeChildSessionOptions build();
+ public static final class TransportModeChildSessionParams.Builder {
+ ctor public TransportModeChildSessionParams.Builder();
+ method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder addInboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
+ method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
+ method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
+ method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams build();
}
- public final class TunnelModeChildSessionOptions extends android.net.ipsec.ike.ChildSessionOptions {
+ public final class TunnelModeChildSessionParams extends android.net.ipsec.ike.ChildSessionParams {
}
- public static final class TunnelModeChildSessionOptions.Builder {
- ctor public TunnelModeChildSessionOptions.Builder();
- method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
- method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalAddressRequest(int);
- method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalAddressRequest(@NonNull java.net.InetAddress, int);
- method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalDhcpServerRequest(int);
- method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalDhcpServerRequest(@NonNull java.net.InetAddress);
- method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalDnsServerRequest(int);
- method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalDnsServerRequest(@NonNull java.net.InetAddress);
- method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addInternalSubnetRequest(int);
- method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
- method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
- method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionOptions build();
+ public static final class TunnelModeChildSessionParams.Builder {
+ ctor public TunnelModeChildSessionParams.Builder();
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addInboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addInternalAddressRequest(int);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addInternalAddressRequest(@NonNull java.net.InetAddress, int);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addInternalDhcpServerRequest(int);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addInternalDhcpServerRequest(@NonNull java.net.InetAddress);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addInternalDnsServerRequest(int);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addInternalDnsServerRequest(@NonNull java.net.InetAddress);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addInternalSubnetRequest(int);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams build();
}
}
@@ -5341,32 +5374,6 @@
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApInfo> CREATOR;
}
- public final class WifiActivityEnergyInfo implements android.os.Parcelable {
- ctor public WifiActivityEnergyInfo(long, int, long, long, long, long, long);
- method public int describeContents();
- method public long getControllerEnergyUsedMicroJoules();
- method public long getControllerIdleDurationMillis();
- method public long getControllerRxDurationMillis();
- method public long getControllerScanDurationMillis();
- method public long getControllerTxDurationMillis();
- method public int getStackState();
- method public long getTimeSinceBootMillis();
- method public boolean isValid();
- method public void setControllerEnergyUsedMicroJoules(long);
- method public void setControllerIdleDurationMillis(long);
- method public void setControllerRxDurationMillis(long);
- method public void setControllerScanDurationMillis(long);
- method public void setControllerTxDurationMillis(long);
- method public void setStackState(int);
- method public void setTimeSinceBootMillis(long);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiActivityEnergyInfo> CREATOR;
- field public static final int STACK_STATE_INVALID = 0; // 0x0
- field public static final int STACK_STATE_STATE_ACTIVE = 1; // 0x1
- field public static final int STACK_STATE_STATE_IDLE = 3; // 0x3
- field public static final int STACK_STATE_STATE_SCANNING = 2; // 0x2
- }
-
public final class WifiClient implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.net.MacAddress getMacAddress();
@@ -5503,6 +5510,7 @@
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
method public int getVerboseLoggingLevel();
+ method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void getWifiActivityEnergyInfoAsync(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener);
method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
method public boolean isApMacRandomizationSupported();
@@ -5606,6 +5614,10 @@
method public default void select(@NonNull android.net.wifi.WifiConfiguration);
}
+ public static interface WifiManager.OnWifiActivityEnergyInfoListener {
+ method public void onWifiActivityEnergyInfo(@Nullable android.os.connectivity.WifiActivityEnergyInfo);
+ }
+
public static interface WifiManager.OnWifiUsabilityStatsListener {
method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry);
}
@@ -6367,6 +6379,8 @@
}
public class PowerWhitelistManager {
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean addToWhitelist(@NonNull String);
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public int addToWhitelist(@NonNull java.util.List<java.lang.String>);
method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public void whitelistAppTemporarily(@NonNull String, long);
method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public long whitelistAppTemporarilyForEvent(@NonNull String, int, @NonNull String);
field public static final int EVENT_MMS = 2; // 0x2
@@ -6608,6 +6622,32 @@
field @NonNull public static final android.os.Parcelable.Creator<android.os.connectivity.CellularBatteryStats> CREATOR;
}
+ public final class WifiActivityEnergyInfo implements android.os.Parcelable {
+ ctor public WifiActivityEnergyInfo(long, int, long, long, long, long, long);
+ method public int describeContents();
+ method public long getControllerEnergyUsedMicroJoules();
+ method public long getControllerIdleDurationMillis();
+ method public long getControllerRxDurationMillis();
+ method public long getControllerScanDurationMillis();
+ method public long getControllerTxDurationMillis();
+ method public int getStackState();
+ method public long getTimeSinceBootMillis();
+ method public boolean isValid();
+ method public void setControllerEnergyUsedMicroJoules(long);
+ method public void setControllerIdleDurationMillis(long);
+ method public void setControllerRxDurationMillis(long);
+ method public void setControllerScanDurationMillis(long);
+ method public void setControllerTxDurationMillis(long);
+ method public void setStackState(int);
+ method public void setTimeSinceBootMillis(long);
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.os.connectivity.WifiActivityEnergyInfo> CREATOR;
+ field public static final int STACK_STATE_INVALID = 0; // 0x0
+ field public static final int STACK_STATE_STATE_ACTIVE = 1; // 0x1
+ field public static final int STACK_STATE_STATE_IDLE = 3; // 0x3
+ field public static final int STACK_STATE_STATE_SCANNING = 2; // 0x2
+ }
+
public final class WifiBatteryStats implements android.os.Parcelable {
method public int describeContents();
method public long getEnergyConsumedMaMillis();
@@ -6712,6 +6752,8 @@
public final class PermissionManager {
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public int getRuntimePermissionsVersion();
method @NonNull public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions();
+ method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS) public void grantDefaultPermissionsToLuiApp(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
+ method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS) public void revokeDefaultPermissionsFromLuiApps(@NonNull String[], @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public void setRuntimePermissionsVersion(@IntRange(from=0) int);
}
@@ -6825,7 +6867,6 @@
package android.provider {
public class BlockedNumberContract {
- field @NonNull public static final android.net.Uri AUTHORITY_URI;
field public static final String METHOD_NOTIFY_EMERGENCY_CONTACT = "notify_emergency_contact";
field public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number";
field public static final String RES_BLOCK_STATUS = "block_status";
@@ -7073,6 +7114,8 @@
field public static final String DEVICE_DEMO_MODE = "device_demo_mode";
field public static final String DEVICE_PROVISIONING_MOBILE_DATA_ENABLED = "device_provisioning_mobile_data";
field public static final String EUICC_PROVISIONED = "euicc_provisioned";
+ field public static final String EUICC_SUPPORTED_COUNTRIES = "euicc_supported_countries";
+ field public static final String EUICC_UNSUPPORTED_COUNTRIES = "euicc_unsupported_countries";
field public static final String INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT = "install_carrier_app_notification_persistent";
field public static final String INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS = "install_carrier_app_notification_sleep_millis";
field public static final String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
@@ -9384,6 +9427,7 @@
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCarrierPrivilegedPackagesForAllActiveSubscriptions();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 3ddbbf8..3ce8c5e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1796,7 +1796,6 @@
}
public class DeviceIdleManager {
- method @RequiresPermission("android.permission.DEVICE_POWER") public int addPowerSaveWhitelistApps(@NonNull java.util.List<java.lang.String>);
method @NonNull public String[] getSystemPowerWhitelist();
method @NonNull public String[] getSystemPowerWhitelistExceptIdle();
}
@@ -2045,6 +2044,8 @@
}
public class PowerWhitelistManager {
+ method @RequiresPermission("android.permission.DEVICE_POWER") public boolean addToWhitelist(@NonNull String);
+ method @RequiresPermission("android.permission.DEVICE_POWER") public int addToWhitelist(@NonNull java.util.List<java.lang.String>);
method @RequiresPermission("android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST") public void whitelistAppTemporarily(@NonNull String, long);
method @RequiresPermission("android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST") public long whitelistAppTemporarilyForEvent(@NonNull String, int, @NonNull String);
field public static final int EVENT_MMS = 2; // 0x2
diff --git a/api/test-lint-baseline.txt b/api/test-lint-baseline.txt
index 3aa8187..a8c4db3 100644
--- a/api/test-lint-baseline.txt
+++ b/api/test-lint-baseline.txt
@@ -8,35 +8,35 @@
ActionValue: android.location.Location#EXTRA_NO_GPS_LOCATION:
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_ADDITIONAL_CALL_INFO:
- Inconsistent extra value; expected `android.telephony.ims.extra.ADDITIONAL_CALL_INFO`, was `AdditionalCallInfo`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CALL_RAT_TYPE:
- Inconsistent extra value; expected `android.telephony.ims.extra.CALL_RAT_TYPE`, was `CallRadioTech`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CHILD_NUMBER:
- Inconsistent extra value; expected `android.telephony.ims.extra.CHILD_NUMBER`, was `ChildNum`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CNA:
- Inconsistent extra value; expected `android.telephony.ims.extra.CNA`, was `cna`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CNAP:
- Inconsistent extra value; expected `android.telephony.ims.extra.CNAP`, was `cnap`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_CODEC:
- Inconsistent extra value; expected `android.telephony.ims.extra.CODEC`, was `Codec`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_DIALSTRING:
- Inconsistent extra value; expected `android.telephony.ims.extra.DIALSTRING`, was `dialstring`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_DISPLAY_TEXT:
- Inconsistent extra value; expected `android.telephony.ims.extra.DISPLAY_TEXT`, was `DisplayText`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_EMERGENCY_CALL:
- Inconsistent extra value; expected `android.telephony.ims.extra.EMERGENCY_CALL`, was `e_call`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_IS_CALL_PULL:
- Inconsistent extra value; expected `android.telephony.ims.extra.IS_CALL_PULL`, was `CallPull`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_OI:
- Inconsistent extra value; expected `android.telephony.ims.extra.OI`, was `oi`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_OIR:
- Inconsistent extra value; expected `android.telephony.ims.extra.OIR`, was `oir`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_REMOTE_URI:
- Inconsistent extra value; expected `android.telephony.ims.extra.REMOTE_URI`, was `remote_uri`
+
ActionValue: android.telephony.ims.ImsCallProfile#EXTRA_USSD:
- Inconsistent extra value; expected `android.telephony.ims.extra.USSD`, was `ussd`
+
ActionValue: android.telephony.ims.ImsReasonInfo#EXTRA_MSG_SERVICE_NOT_AUTHORIZED:
- Inconsistent extra value; expected `android.telephony.ims.extra.MSG_SERVICE_NOT_AUTHORIZED`, was `Forbidden. Not Authorized for Service`
+
ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_CLEANUP:
ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_DOWNLOAD_RESULT_INTERNAL:
@@ -100,13 +100,13 @@
ArrayReturn: android.security.keystore.AttestationUtils#attestDeviceIds(android.content.Context, int[], byte[]):
ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
- Method parameter should be Collection<ImsSsInfo> (or subclass) instead of raw array; was `android.telephony.ims.ImsSsInfo[]`
+
ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]) parameter #1:
- Method parameter should be Collection<ImsCallForwardInfo> (or subclass) instead of raw array; was `android.telephony.ims.ImsCallForwardInfo[]`
+
ArrayReturn: android.telephony.ims.ImsUtListener#onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
- Method parameter should be Collection<ImsSsInfo> (or subclass) instead of raw array; was `android.telephony.ims.ImsSsInfo[]`
+
ArrayReturn: android.telephony.ims.stub.ImsRegistrationImplBase#onSubscriberAssociatedUriChanged(android.net.Uri[]) parameter #0:
- Method parameter should be Collection<Uri> (or subclass) instead of raw array; was `android.net.Uri[]`
+
ArrayReturn: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #0:
ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
@@ -268,7 +268,7 @@
ConcreteCollection: android.service.autofill.UserData#getFieldClassificationAlgorithms():
ConcreteCollection: android.telephony.ims.ImsConferenceState#mParticipants:
- Field type is concrete collection (`java.util.HashMap`); must be higher-level interface
+
ContextFirst: android.os.VibrationEffect#get(android.net.Uri, android.content.Context) parameter #1:
@@ -338,9 +338,9 @@
ExecutorRegistration: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler):
ExecutorRegistration: android.telephony.ims.stub.ImsCallSessionImplBase#setListener(android.telephony.ims.ImsCallSessionListener):
- Registration methods should have overload that accepts delivery Executor: `setListener`
+
ExecutorRegistration: android.telephony.ims.stub.ImsUtImplBase#setListener(android.telephony.ims.ImsUtListener):
- Registration methods should have overload that accepts delivery Executor: `setListener`
+
ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
@@ -460,11 +460,13 @@
InternalField: android.telephony.ims.ImsConferenceState#mParticipants:
- Internal field mParticipants must not be exposed
+
KotlinOperator: android.os.WorkSource#get(int):
+KotlinOperator: android.util.SparseArrayMap#get(int, String):
+ Method can be invoked with an indexing operator from Kotlin: `get` (this is usually desirable; just make sure it makes sense for this type of object)
ListenerInterface: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener:
@@ -474,9 +476,9 @@
ListenerInterface: android.os.IncidentManager.AuthListener:
ListenerInterface: android.telephony.ims.ImsCallSessionListener:
- Listeners should be an interface, or otherwise renamed Callback: ImsCallSessionListener
+
ListenerInterface: android.telephony.ims.ImsUtListener:
- Listeners should be an interface, or otherwise renamed Callback: ImsUtListener
+
ListenerLast: android.hardware.camera2.CameraDevice#createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) parameter #4:
@@ -496,17 +498,17 @@
ManagerLookup: android.telephony.ims.ImsMmTelManager#createForSubscriptionId(int):
- Managers must always be obtained from Context (`createForSubscriptionId`)
+
ManagerLookup: android.telephony.ims.ProvisioningManager#createForSubscriptionId(int):
- Managers must always be obtained from Context (`createForSubscriptionId`)
+
MethodNameTense: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToEnable():
- Unexpected tense; probably meant `enabled`, was `getCapabilitiesToEnable`
+
MethodNameUnits: android.telephony.ims.ImsCallForwardInfo#getTimeSeconds():
- Returned time values must be in milliseconds, was `getTimeSeconds`
+
MinMaxConstant: android.os.UserHandle#MIN_SECONDARY_USER_ID:
@@ -1460,7 +1462,7 @@
MissingNullability: android.telecom.PhoneAccountSuggestionService#onBind(android.content.Intent) parameter #0:
MissingNullability: android.telephony.CallQuality#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `dest` in method `writeToParcel`
+
MissingNullability: android.telephony.DataSpecificRegistrationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
MissingNullability: android.telephony.LteVopsSupportInfo#writeToParcel(android.os.Parcel, int) parameter #0:
@@ -1478,9 +1480,9 @@
MissingNullability: android.telephony.TelephonyManager#checkCarrierPrivilegesForPackage(String) parameter #0:
MissingNullability: android.telephony.TelephonyManager#getCarrierPackageNamesForIntent(android.content.Intent):
- Missing nullability on method `getCarrierPackageNamesForIntent` return
+
MissingNullability: android.telephony.TelephonyManager#getCarrierPackageNamesForIntent(android.content.Intent) parameter #0:
- Missing nullability on parameter `intent` in method `getCarrierPackageNamesForIntent`
+
MissingNullability: android.telephony.TelephonyManager#getLine1AlphaTag():
MissingNullability: android.telephony.TelephonyManager#getRadioHalVersion():
@@ -1518,315 +1520,315 @@
MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #8:
MissingNullability: android.telephony.ims.ImsCallForwardInfo#getNumber():
- Missing nullability on method `getNumber` return
+
MissingNullability: android.telephony.ims.ImsCallForwardInfo#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `out` in method `writeToParcel`
+
MissingNullability: android.telephony.ims.ImsCallProfile#ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile) parameter #2:
- Missing nullability on parameter `callExtras` in method `ImsCallProfile`
+
MissingNullability: android.telephony.ims.ImsCallProfile#ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile) parameter #3:
- Missing nullability on parameter `mediaProfile` in method `ImsCallProfile`
+
MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String):
- Missing nullability on method `getCallExtra` return
+
MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String) parameter #0:
- Missing nullability on parameter `name` in method `getCallExtra`
+
MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String):
- Missing nullability on method `getCallExtra` return
+
MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String) parameter #0:
- Missing nullability on parameter `name` in method `getCallExtra`
+
MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtra(String, String) parameter #1:
- Missing nullability on parameter `defaultValue` in method `getCallExtra`
+
MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraBoolean(String) parameter #0:
- Missing nullability on parameter `name` in method `getCallExtraBoolean`
+
MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraBoolean(String, boolean) parameter #0:
- Missing nullability on parameter `name` in method `getCallExtraBoolean`
+
MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraInt(String) parameter #0:
- Missing nullability on parameter `name` in method `getCallExtraInt`
+
MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtraInt(String, int) parameter #0:
- Missing nullability on parameter `name` in method `getCallExtraInt`
+
MissingNullability: android.telephony.ims.ImsCallProfile#getCallExtras():
- Missing nullability on method `getCallExtras` return
+
MissingNullability: android.telephony.ims.ImsCallProfile#getMediaProfile():
- Missing nullability on method `getMediaProfile` return
+
MissingNullability: android.telephony.ims.ImsCallProfile#getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `callProfile` in method `getVideoStateFromImsCallProfile`
+
MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtra(String, String) parameter #0:
- Missing nullability on parameter `name` in method `setCallExtra`
+
MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtra(String, String) parameter #1:
- Missing nullability on parameter `value` in method `setCallExtra`
+
MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtraBoolean(String, boolean) parameter #0:
- Missing nullability on parameter `name` in method `setCallExtraBoolean`
+
MissingNullability: android.telephony.ims.ImsCallProfile#setCallExtraInt(String, int) parameter #0:
- Missing nullability on parameter `name` in method `setCallExtraInt`
+
MissingNullability: android.telephony.ims.ImsCallProfile#updateCallExtras(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `profile` in method `updateCallExtras`
+
MissingNullability: android.telephony.ims.ImsCallProfile#updateCallType(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `profile` in method `updateCallType`
+
MissingNullability: android.telephony.ims.ImsCallProfile#updateMediaProfile(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `profile` in method `updateMediaProfile`
+
MissingNullability: android.telephony.ims.ImsCallProfile#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `out` in method `writeToParcel`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
- Missing nullability on parameter `reasonInfo` in method `callSessionConferenceExtendFailed`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `newSession` in method `callSessionConferenceExtendReceived`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
- Missing nullability on parameter `profile` in method `callSessionConferenceExtendReceived`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `newSession` in method `callSessionConferenceExtended`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
- Missing nullability on parameter `profile` in method `callSessionConferenceExtended`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState) parameter #0:
- Missing nullability on parameter `state` in method `callSessionConferenceStateUpdated`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo) parameter #2:
- Missing nullability on parameter `reasonInfo` in method `callSessionHandover`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo) parameter #2:
- Missing nullability on parameter `reasonInfo` in method `callSessionHandoverFailed`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHeld(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `profile` in method `callSessionHeld`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHoldFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
- Missing nullability on parameter `reasonInfo` in method `callSessionHoldFailed`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionHoldReceived(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `profile` in method `callSessionHoldReceived`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInitiated(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `profile` in method `callSessionInitiated`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
- Missing nullability on parameter `reasonInfo` in method `callSessionInitiatedFailed`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
- Missing nullability on parameter `reasonInfo` in method `callSessionInviteParticipantsRequestFailed`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase) parameter #0:
- Missing nullability on parameter `newSession` in method `callSessionMergeComplete`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
- Missing nullability on parameter `reasonInfo` in method `callSessionMergeFailed`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `newSession` in method `callSessionMergeStarted`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile) parameter #1:
- Missing nullability on parameter `profile` in method `callSessionMergeStarted`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
- Missing nullability on parameter `profile` in method `callSessionProgressing`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
- Missing nullability on parameter `reasonInfo` in method `callSessionRemoveParticipantsRequestFailed`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumeFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
- Missing nullability on parameter `reasonInfo` in method `callSessionResumeFailed`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumeReceived(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `profile` in method `callSessionResumeReceived`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionResumed(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `profile` in method `callSessionResumed`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRttMessageReceived(String) parameter #0:
- Missing nullability on parameter `rttMessage` in method `callSessionRttMessageReceived`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `callProfile` in method `callSessionRttModifyRequestReceived`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification) parameter #0:
- Missing nullability on parameter `suppSrvNotification` in method `callSessionSuppServiceReceived`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionTerminated(android.telephony.ims.ImsReasonInfo) parameter #0:
- Missing nullability on parameter `reasonInfo` in method `callSessionTerminated`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo) parameter #0:
- Missing nullability on parameter `reasonInfo` in method `callSessionUpdateFailed`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdateReceived(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `profile` in method `callSessionUpdateReceived`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUpdated(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `profile` in method `callSessionUpdated`
+
MissingNullability: android.telephony.ims.ImsCallSessionListener#callSessionUssdMessageReceived(int, String) parameter #1:
- Missing nullability on parameter `ussdMessage` in method `callSessionUssdMessageReceived`
+
MissingNullability: android.telephony.ims.ImsConferenceState#getConnectionStateForStatus(String) parameter #0:
- Missing nullability on parameter `status` in method `getConnectionStateForStatus`
+
MissingNullability: android.telephony.ims.ImsConferenceState#mParticipants:
- Missing nullability on field `mParticipants` in class `class android.telephony.ims.ImsConferenceState`
+
MissingNullability: android.telephony.ims.ImsConferenceState#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `out` in method `writeToParcel`
+
MissingNullability: android.telephony.ims.ImsExternalCallState#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `out` in method `writeToParcel`
+
MissingNullability: android.telephony.ims.ImsReasonInfo#ImsReasonInfo(int, int, String) parameter #2:
- Missing nullability on parameter `extraMessage` in method `ImsReasonInfo`
+
MissingNullability: android.telephony.ims.ImsReasonInfo#getExtraMessage():
- Missing nullability on method `getExtraMessage` return
+
MissingNullability: android.telephony.ims.ImsReasonInfo#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `out` in method `writeToParcel`
+
MissingNullability: android.telephony.ims.ImsService#createMmTelFeature(int):
- Missing nullability on method `createMmTelFeature` return
+
MissingNullability: android.telephony.ims.ImsService#createRcsFeature(int):
- Missing nullability on method `createRcsFeature` return
+
MissingNullability: android.telephony.ims.ImsService#getConfig(int):
- Missing nullability on method `getConfig` return
+
MissingNullability: android.telephony.ims.ImsService#getRegistration(int):
- Missing nullability on method `getRegistration` return
+
MissingNullability: android.telephony.ims.ImsService#onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) parameter #0:
- Missing nullability on parameter `c` in method `onUpdateSupportedImsFeatures`
+
MissingNullability: android.telephony.ims.ImsService#querySupportedImsFeatures():
- Missing nullability on method `querySupportedImsFeatures` return
+
MissingNullability: android.telephony.ims.ImsSsData#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `out` in method `writeToParcel`
+
MissingNullability: android.telephony.ims.ImsSsInfo#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `out` in method `writeToParcel`
+
MissingNullability: android.telephony.ims.ImsStreamMediaProfile#copyFrom(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
- Missing nullability on parameter `profile` in method `copyFrom`
+
MissingNullability: android.telephony.ims.ImsStreamMediaProfile#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `out` in method `writeToParcel`
+
MissingNullability: android.telephony.ims.ImsSuppServiceNotification#ImsSuppServiceNotification(int, int, int, int, String, String[]) parameter #4:
- Missing nullability on parameter `number` in method `ImsSuppServiceNotification`
+
MissingNullability: android.telephony.ims.ImsSuppServiceNotification#ImsSuppServiceNotification(int, int, int, int, String, String[]) parameter #5:
- Missing nullability on parameter `history` in method `ImsSuppServiceNotification`
+
MissingNullability: android.telephony.ims.ImsSuppServiceNotification#history:
- Missing nullability on field `history` in class `class android.telephony.ims.ImsSuppServiceNotification`
+
MissingNullability: android.telephony.ims.ImsSuppServiceNotification#number:
- Missing nullability on field `number` in class `class android.telephony.ims.ImsSuppServiceNotification`
+
MissingNullability: android.telephony.ims.ImsSuppServiceNotification#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `out` in method `writeToParcel`
+
MissingNullability: android.telephony.ims.ImsUtListener#onSupplementaryServiceIndication(android.telephony.ims.ImsSsData) parameter #0:
- Missing nullability on parameter `ssData` in method `onSupplementaryServiceIndication`
+
MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
- Missing nullability on parameter `cbInfo` in method `onUtConfigurationCallBarringQueried`
+
MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]) parameter #1:
- Missing nullability on parameter `cfInfo` in method `onUtConfigurationCallForwardQueried`
+
MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]) parameter #1:
- Missing nullability on parameter `cwInfo` in method `onUtConfigurationCallWaitingQueried`
+
MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationQueried(int, android.os.Bundle) parameter #1:
- Missing nullability on parameter `configuration` in method `onUtConfigurationQueried`
+
MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
- Missing nullability on parameter `error` in method `onUtConfigurationQueryFailed`
+
MissingNullability: android.telephony.ims.ImsUtListener#onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
- Missing nullability on parameter `error` in method `onUtConfigurationUpdateFailed`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities) parameter #0:
- Missing nullability on parameter `CameraCapabilities` in method `changeCameraCapabilities`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #0:
- Missing nullability on parameter `fromProfile` in method `onSendSessionModifyRequest`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #1:
- Missing nullability on parameter `toProfile` in method `onSendSessionModifyRequest`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSendSessionModifyResponse(android.telecom.VideoProfile) parameter #0:
- Missing nullability on parameter `responseProfile` in method `onSendSessionModifyResponse`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetCamera(String) parameter #0:
- Missing nullability on parameter `cameraId` in method `onSetCamera`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetCamera(String, int) parameter #0:
- Missing nullability on parameter `cameraId` in method `onSetCamera`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetDisplaySurface(android.view.Surface) parameter #0:
- Missing nullability on parameter `surface` in method `onSetDisplaySurface`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetPauseImage(android.net.Uri) parameter #0:
- Missing nullability on parameter `uri` in method `onSetPauseImage`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#onSetPreviewSurface(android.view.Surface) parameter #0:
- Missing nullability on parameter `surface` in method `onSetPreviewSurface`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyRequest(android.telecom.VideoProfile) parameter #0:
- Missing nullability on parameter `VideoProfile` in method `receiveSessionModifyRequest`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #1:
- Missing nullability on parameter `requestedProfile` in method `receiveSessionModifyResponse`
+
MissingNullability: android.telephony.ims.ImsVideoCallProvider#receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile) parameter #2:
- Missing nullability on parameter `responseProfile` in method `receiveSessionModifyResponse`
+
MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToDisable():
- Missing nullability on method `getCapabilitiesToDisable` return
+
MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#getCapabilitiesToEnable():
- Missing nullability on method `getCapabilitiesToEnable` return
+
MissingNullability: android.telephony.ims.feature.CapabilityChangeRequest#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `dest` in method `writeToParcel`
+
MissingNullability: android.telephony.ims.feature.ImsFeature#changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy) parameter #0:
- Missing nullability on parameter `request` in method `changeEnabledCapabilities`
+
MissingNullability: android.telephony.ims.feature.ImsFeature#changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy) parameter #1:
- Missing nullability on parameter `c` in method `changeEnabledCapabilities`
+
MissingNullability: android.telephony.ims.feature.MmTelFeature#queryCapabilityStatus():
- Missing nullability on method `queryCapabilityStatus` return
+
MissingNullability: android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities) parameter #0:
- Missing nullability on parameter `c` in method `MmTelCapabilities`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#accept(int, android.telephony.ims.ImsStreamMediaProfile) parameter #1:
- Missing nullability on parameter `profile` in method `accept`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#deflect(String) parameter #0:
- Missing nullability on parameter `deflectNumber` in method `deflect`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#extendToConference(String[]) parameter #0:
- Missing nullability on parameter `participants` in method `extendToConference`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getCallId():
- Missing nullability on method `getCallId` return
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getCallProfile():
- Missing nullability on method `getCallProfile` return
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getImsVideoCallProvider():
- Missing nullability on method `getImsVideoCallProvider` return
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getLocalCallProfile():
- Missing nullability on method `getLocalCallProfile` return
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getProperty(String):
- Missing nullability on method `getProperty` return
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getProperty(String) parameter #0:
- Missing nullability on parameter `name` in method `getProperty`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#getRemoteCallProfile():
- Missing nullability on method `getRemoteCallProfile` return
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#hold(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
- Missing nullability on parameter `profile` in method `hold`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#inviteParticipants(String[]) parameter #0:
- Missing nullability on parameter `participants` in method `inviteParticipants`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#removeParticipants(String[]) parameter #0:
- Missing nullability on parameter `participants` in method `removeParticipants`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#resume(android.telephony.ims.ImsStreamMediaProfile) parameter #0:
- Missing nullability on parameter `profile` in method `resume`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendDtmf(char, android.os.Message) parameter #1:
- Missing nullability on parameter `result` in method `sendDtmf`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendRttMessage(String) parameter #0:
- Missing nullability on parameter `rttMessage` in method `sendRttMessage`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendRttModifyRequest(android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `toProfile` in method `sendRttModifyRequest`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#sendUssd(String) parameter #0:
- Missing nullability on parameter `ussdMessage` in method `sendUssd`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#setListener(android.telephony.ims.ImsCallSessionListener) parameter #0:
- Missing nullability on parameter `listener` in method `setListener`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#start(String, android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `callee` in method `start`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#start(String, android.telephony.ims.ImsCallProfile) parameter #1:
- Missing nullability on parameter `profile` in method `start`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#startConference(String[], android.telephony.ims.ImsCallProfile) parameter #0:
- Missing nullability on parameter `participants` in method `startConference`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#startConference(String[], android.telephony.ims.ImsCallProfile) parameter #1:
- Missing nullability on parameter `profile` in method `startConference`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase#update(int, android.telephony.ims.ImsStreamMediaProfile) parameter #1:
- Missing nullability on parameter `profile` in method `update`
+
MissingNullability: android.telephony.ims.stub.ImsCallSessionImplBase.State#toString(int):
- Missing nullability on method `toString` return
+
MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#getConfigString(int):
- Missing nullability on method `getConfigString` return
+
MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#notifyProvisionedValueChanged(int, String) parameter #1:
- Missing nullability on parameter `value` in method `notifyProvisionedValueChanged`
+
MissingNullability: android.telephony.ims.stub.ImsConfigImplBase#setConfig(int, String) parameter #1:
- Missing nullability on parameter `value` in method `setConfig`
+
MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration#getServiceFeatures():
- Missing nullability on method `getServiceFeatures` return
+
MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
- Missing nullability on parameter `dest` in method `writeToParcel`
+
MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration.Builder#addFeature(int, int):
- Missing nullability on method `addFeature` return
+
MissingNullability: android.telephony.ims.stub.ImsFeatureConfiguration.Builder#build():
- Missing nullability on method `build` return
+
MissingNullability: android.telephony.ims.stub.ImsMultiEndpointImplBase#onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>) parameter #0:
- Missing nullability on parameter `externalCallDialogs` in method `onImsExternalCallStateUpdate`
+
MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onDeregistered(android.telephony.ims.ImsReasonInfo) parameter #0:
- Missing nullability on parameter `info` in method `onDeregistered`
+
MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onSubscriberAssociatedUriChanged(android.net.Uri[]) parameter #0:
- Missing nullability on parameter `uris` in method `onSubscriberAssociatedUriChanged`
+
MissingNullability: android.telephony.ims.stub.ImsRegistrationImplBase#onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo) parameter #1:
- Missing nullability on parameter `info` in method `onTechnologyChangeFailed`
+
MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#getSmsFormat():
- Missing nullability on method `getSmsFormat` return
+
MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsReceived(int, String, byte[]) parameter #1:
- Missing nullability on parameter `format` in method `onSmsReceived`
+
MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsReceived(int, String, byte[]) parameter #2:
- Missing nullability on parameter `pdu` in method `onSmsReceived`
+
MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, String, byte[]) parameter #1:
- Missing nullability on parameter `format` in method `onSmsStatusReportReceived`
+
MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, String, byte[]) parameter #2:
- Missing nullability on parameter `pdu` in method `onSmsStatusReportReceived`
+
MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, int, String, byte[]) parameter #2:
- Missing nullability on parameter `format` in method `onSmsStatusReportReceived`
+
MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#onSmsStatusReportReceived(int, int, String, byte[]) parameter #3:
- Missing nullability on parameter `pdu` in method `onSmsStatusReportReceived`
+
MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #2:
- Missing nullability on parameter `format` in method `sendSms`
+
MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #3:
- Missing nullability on parameter `smsc` in method `sendSms`
+
MissingNullability: android.telephony.ims.stub.ImsSmsImplBase#sendSms(int, int, String, String, boolean, byte[]) parameter #5:
- Missing nullability on parameter `pdu` in method `sendSms`
+
MissingNullability: android.telephony.ims.stub.ImsUtImplBase#queryCallForward(int, String) parameter #1:
- Missing nullability on parameter `number` in method `queryCallForward`
+
MissingNullability: android.telephony.ims.stub.ImsUtImplBase#setListener(android.telephony.ims.ImsUtListener) parameter #0:
- Missing nullability on parameter `listener` in method `setListener`
+
MissingNullability: android.telephony.ims.stub.ImsUtImplBase#transact(android.os.Bundle) parameter #0:
- Missing nullability on parameter `ssInfo` in method `transact`
+
MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallBarring(int, int, String[]) parameter #2:
- Missing nullability on parameter `barrList` in method `updateCallBarring`
+
MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallBarringForServiceClass(int, int, String[], int) parameter #2:
- Missing nullability on parameter `barrList` in method `updateCallBarringForServiceClass`
+
MissingNullability: android.telephony.ims.stub.ImsUtImplBase#updateCallForward(int, int, String, int, int) parameter #2:
- Missing nullability on parameter `number` in method `updateCallForward`
+
MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String) parameter #0:
@@ -2278,7 +2280,7 @@
NotCloseable: android.os.HwParcel:
NotCloseable: android.telephony.ims.stub.ImsUtImplBase:
- Classes that release resources (close()) should implement AutoClosable and CloseGuard: class android.telephony.ims.stub.ImsUtImplBase
+
OnNameExpected: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.PrintWriter, String[]):
@@ -2292,21 +2294,21 @@
OnNameExpected: android.service.quicksettings.TileService#isQuickSettingsSupported():
OnNameExpected: android.telephony.ims.ImsService#createMmTelFeature(int):
- If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+
OnNameExpected: android.telephony.ims.ImsService#createRcsFeature(int):
- If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+
OnNameExpected: android.telephony.ims.ImsService#disableIms(int):
- If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+
OnNameExpected: android.telephony.ims.ImsService#enableIms(int):
- If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+
OnNameExpected: android.telephony.ims.ImsService#getConfig(int):
- If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+
OnNameExpected: android.telephony.ims.ImsService#getRegistration(int):
- If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+
OnNameExpected: android.telephony.ims.ImsService#querySupportedImsFeatures():
- If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+
OnNameExpected: android.telephony.ims.ImsService#readyForFeatureCreation():
- If implemented by developer, should follow the on<Something> style; otherwise consider marking final
+
OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#dispose(int):
OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int):
@@ -2446,7 +2448,7 @@
RethrowRemoteException: android.os.IHwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int):
RethrowRemoteException: android.telephony.ims.ImsService#onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration):
- Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
+
RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
@@ -2526,7 +2528,7 @@
SamShouldBeLast: android.service.autofill.InternalTransformation#batchApply(android.service.autofill.ValueFinder, android.widget.RemoteViews, java.util.ArrayList<android.util.Pair<java.lang.Integer,android.service.autofill.InternalTransformation>>):
SamShouldBeLast: android.telephony.ims.ImsMmTelManager#getFeatureState(java.util.function.Consumer<java.lang.Integer>, java.util.concurrent.Executor):
- SAM-compatible parameters (such as parameter 1, "callback", in android.telephony.ims.ImsMmTelManager.getFeatureState) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+
SamShouldBeLast: android.view.Choreographer#postCallback(int, Runnable, Object):
SamShouldBeLast: android.view.Choreographer#postCallbackDelayed(int, Runnable, Object, long):
@@ -2599,6 +2601,8 @@
UserHandle: android.app.role.RoleManager#removeRoleHolderAsUser(String, String, int, android.os.UserHandle, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Boolean>):
+UserHandle: android.companion.CompanionDeviceManager#isDeviceAssociated(String, android.net.MacAddress, android.os.UserHandle):
+ When a method overload is needed to target a specific UserHandle, callers should be directed to use Context.createPackageContextAsUser() and re-obtain the relevant Manager, and no new API should be added
UserHandle: android.content.pm.PackageManager#getInstallReason(String, android.os.UserHandle):
UserHandle: android.content.pm.PackageManager#getPermissionFlags(String, String, android.os.UserHandle):
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 1fd3abf..d10a661 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1275,7 +1275,7 @@
// Permission check not necessary as it's meant for applications to write to
// statsd.
android::util::stats_write(util::APP_BREADCRUMB_REPORTED,
- IPCThreadState::self()->getCallingUid(), label,
+ (int32_t) IPCThreadState::self()->getCallingUid(), label,
state);
return Status::ok();
}
@@ -1295,7 +1295,18 @@
const sp<android::os::IPullAtomCallback>& pullerCallback) {
ENFORCE_UID(AID_SYSTEM);
- VLOG("StatsService::registerPuller called.");
+ VLOG("StatsService::registerPullAtomCallback called.");
+ mPullerManager->RegisterPullAtomCallback(uid, atomTag, coolDownNs, timeoutNs, additiveFields,
+ pullerCallback);
+ return Status::ok();
+}
+
+Status StatsService::registerNativePullAtomCallback(int32_t atomTag, int64_t coolDownNs,
+ int64_t timeoutNs, const std::vector<int32_t>& additiveFields,
+ const sp<android::os::IPullAtomCallback>& pullerCallback) {
+
+ VLOG("StatsService::registerNativePullAtomCallback called.");
+ int32_t uid = IPCThreadState::self()->getCallingUid();
mPullerManager->RegisterPullAtomCallback(uid, atomTag, coolDownNs, timeoutNs, additiveFields,
pullerCallback);
return Status::ok();
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 6d40007..8c98e7b 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -187,6 +187,13 @@
const sp<android::os::IPullAtomCallback>& pullerCallback) override;
/**
+ * Binder call to register a callback function for a pulled atom.
+ */
+ virtual Status registerNativePullAtomCallback(int32_t atomTag, int64_t coolDownNs,
+ int64_t timeoutNs, const std::vector<int32_t>& additiveFields,
+ const sp<android::os::IPullAtomCallback>& pullerCallback) override;
+
+ /**
* Binder call to unregister any existing callback function for a vendor pulled atom.
*/
virtual Status unregisterPullerCallback(int32_t atomTag, const String16& packageName) override;
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index b9051da..2efb789 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -50,6 +50,7 @@
import "frameworks/base/core/proto/android/stats/launcher/launcher.proto";
import "frameworks/base/core/proto/android/stats/location/location_enums.proto";
import "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.proto";
+import "frameworks/base/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto";
import "frameworks/base/core/proto/android/stats/storage/storage_enums.proto";
import "frameworks/base/core/proto/android/stats/style/style_enums.proto";
import "frameworks/base/core/proto/android/telecomm/enums.proto";
@@ -342,6 +343,16 @@
VmsClientConnectionStateChanged vms_client_connection_state_changed = 230;
GpsLocationStatusReported gps_location_status_reported = 231;
GpsTimeToFirstFixReported gps_time_to_first_fix_reported = 232;
+ MediaProviderScanEvent media_provider_scan_event =
+ 233 [(log_from_module) = "mediaprovider"];
+ MediaProviderDeletionEvent media_provider_deletion_event =
+ 234 [(log_from_module) = "mediaprovider"];
+ MediaProviderPermissionEvent media_provider_permission_event =
+ 235 [(log_from_module) = "mediaprovider"];
+ MediaProviderSchemaChange media_provider_schema_change =
+ 236 [(log_from_module) = "mediaprovider"];
+ MediaProviderIdleMaintenance media_provider_idle_maintenance =
+ 237 [(log_from_module) = "mediaprovider"];
}
// Pulled events will start at field 10000.
@@ -3799,6 +3810,124 @@
optional State state = 2;
}
+/**
+ * Logs when MediaProvider has successfully finished scanning a storage volume.
+ *
+ * Logged from:
+ * packages/providers/MediaProvider/src/com/android/providers/media/scan/ModernMediaScanner.java
+ */
+message MediaProviderScanEvent {
+ enum Reason {
+ // Scan triggered due to unknown reason
+ UNKNOWN = 0;
+ // Scan triggered due to storage volume being mounted
+ MOUNTED = 1;
+ // Scan triggered due to explicit user action or app request
+ DEMAND = 2;
+ // Scan triggered due to idle maintenance
+ IDLE = 3;
+ }
+
+ // Volume type that this event pertains to
+ optional android.stats.mediaprovider.VolumeType volume_type = 1;
+ // Reason why this scan was triggered
+ optional Reason reason = 2;
+ // Total number of files scanned
+ optional int64 item_count = 3;
+ // Duration of scan, normalized per file
+ optional float normalized_duration_millis = 4;
+ // Number of database inserts, normalized per file
+ optional float normalized_insert_count = 5;
+ // Number of database updates, normalized per file
+ optional float normalized_update_count = 6;
+ // Number of database deletes, normalized per file
+ optional float normalized_delete_count = 7;
+}
+
+/**
+ * Logs when an app has asked MediaProvider to delete media belonging to the user.
+ *
+ * Logged from:
+ * packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
+ */
+message MediaProviderDeletionEvent {
+ // Volume type that this event pertains to
+ optional android.stats.mediaprovider.VolumeType volume_type = 1;
+ // Device timestamp when this deletion event occurred
+ optional int64 timestamp_millis = 2;
+ // App that requested deletion
+ optional string package_name = 3;
+ // Number of items that were deleted
+ optional int32 item_count = 4;
+}
+
+/**
+ * Logs when an app has asked MediaProvider to grant them access to media belonging to the user.
+ *
+ * Logged from:
+ * packages/providers/MediaProvider/src/com/android/providers/media/PermissionActivity.java
+ */
+message MediaProviderPermissionEvent {
+ enum Result {
+ UNKNOWN = 0;
+ USER_GRANTED = 1;
+ AUTO_GRANTED = 2;
+ USER_DENIED = 3;
+ USER_DENIED_WITH_PREJUDICE = 4;
+ AUTO_DENIED = 5;
+ }
+
+ // Volume type that this event pertains to
+ optional android.stats.mediaprovider.VolumeType volume_type = 1;
+ // Device timestamp when this permission event occurred
+ optional int64 timestamp_millis = 2;
+ // App that requested permission
+ optional string package_name = 3;
+ // Number of items that were requested
+ optional int32 item_count = 4;
+ // Result of this request
+ optional Result result = 5;
+}
+
+/**
+ * Logs when MediaProvider has finished upgrading or downgrading its database schema.
+ *
+ * Logged from:
+ * packages/providers/MediaProvider/src/com/android/providers/media/DatabaseHelper.java
+ */
+message MediaProviderSchemaChange {
+ // Volume type that this event pertains to
+ optional android.stats.mediaprovider.VolumeType volume_type = 1;
+ // Old database version code
+ optional int32 version_from = 2;
+ // New database version code
+ optional int32 version_to = 3;
+ // Total number of files in database
+ optional int64 item_count = 4;
+ // Duration of schema change, normalized per file
+ optional float normalized_duration_millis = 5;
+}
+
+/**
+ * Logs when MediaProvider has finished an idle maintenance job.
+ *
+ * Logged from:
+ * packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java
+ */
+message MediaProviderIdleMaintenance {
+ // Volume type that this event pertains to
+ optional android.stats.mediaprovider.VolumeType volume_type = 1;
+
+ // Total number of files in database
+ optional int64 item_count = 2;
+ // Duration of idle maintenance, normalized per file
+ optional float normalized_duration_millis = 3;
+ // Number of thumbnails found to be stale, normalized per file
+ optional float normalized_stale_thumbnails = 4;
+ // Number of items found to be expired, normalized per file
+ optional float normalized_expired_media = 5;
+}
+
//////////////////////////////////////////////////////////////////////
// Pulled atoms below this line //
//////////////////////////////////////////////////////////////////////
@@ -5798,10 +5927,10 @@
optional int64 request_id = 1;
// UID of package requesting the permission grant
- optional int32 requesting_uid = 2 [(is_uid) = true];
+ optional int32 uid = 2 [(is_uid) = true];
// Name of package requesting the permission grant
- optional string requesting_package_name = 3;
+ optional string package_name = 3;
// The permission to be granted
optional string permission_name = 4;
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
index 52a1269..69aae3d 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
@@ -86,7 +86,7 @@
ALOGW("Child initialization failed %lld ", (long long)child);
return false;
} else {
- ALOGW("Child initialization success %lld ", (long long)child);
+ VLOG("Child initialization success %lld ", (long long)child);
}
if (allConditionTrackers[childIndex]->isSliced()) {
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index c29b32c..c1f95ee 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -121,10 +121,12 @@
VLOG("~CountMetricProducer() called");
}
-void CountMetricProducer::onStateChanged(int atomId, const HashableDimensionKey& primaryKey,
- int oldState, int newState) {
- VLOG("CountMetric %lld onStateChanged State%d, key %s, %d -> %d", (long long)mMetricId, atomId,
- primaryKey.toString().c_str(), oldState, newState);
+void CountMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
+ const HashableDimensionKey& primaryKey, int oldState,
+ int newState) {
+ VLOG("CountMetric %lld onStateChanged time %lld, State%d, key %s, %d -> %d",
+ (long long)mMetricId, (long long)eventTimeNs, atomId, primaryKey.toString().c_str(),
+ oldState, newState);
}
void CountMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 8b17d88..7b6c7e0 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -52,7 +52,8 @@
virtual ~CountMetricProducer();
- void onStateChanged(int32_t atomId, const HashableDimensionKey& primaryKey, int oldState,
+ void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
+ const HashableDimensionKey& primaryKey, int oldState,
int newState) override;
protected:
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index a513db6..3512f18 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -149,8 +149,8 @@
return mConditionSliced;
};
- void onStateChanged(int atomId, const HashableDimensionKey& primaryKey, int oldState,
- int newState){};
+ void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
+ const HashableDimensionKey& primaryKey, int oldState, int newState){};
// Output the metrics data to [protoOutput]. All metrics reports end with the same timestamp.
// This method clears all the past buckets.
diff --git a/cmds/statsd/src/state/StateListener.h b/cmds/statsd/src/state/StateListener.h
index f2b9a6b..d1af196 100644
--- a/cmds/statsd/src/state/StateListener.h
+++ b/cmds/statsd/src/state/StateListener.h
@@ -38,13 +38,15 @@
* state groups and are responsible for mapping original state values to
* the correct state group.
*
+ * [eventTimeNs]: Time of the state change log event.
* [atomId]: The id of the state atom
* [primaryKey]: The primary field values of the state atom
* [oldState]: Previous state value before state change
* [newState]: Current state value after state change
*/
- virtual void onStateChanged(int32_t atomId, const HashableDimensionKey& primaryKey,
- int oldState, int newState) = 0;
+ virtual void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
+ const HashableDimensionKey& primaryKey, int oldState,
+ int newState) = 0;
};
} // namespace statsd
diff --git a/cmds/statsd/src/state/StateTracker.cpp b/cmds/statsd/src/state/StateTracker.cpp
index e6f6122..90ce1e9 100644
--- a/cmds/statsd/src/state/StateTracker.cpp
+++ b/cmds/statsd/src/state/StateTracker.cpp
@@ -38,49 +38,51 @@
}
void StateTracker::onLogEvent(const LogEvent& event) {
- // parse event for primary field values i.e. primary key
+ int64_t eventTimeNs = event.GetElapsedTimestampNs();
+
+ // Parse event for primary field values i.e. primary key.
HashableDimensionKey primaryKey;
if (mPrimaryFields.size() > 0) {
if (!filterValues(mPrimaryFields, event.getValues(), &primaryKey) ||
primaryKey.getValues().size() != mPrimaryFields.size()) {
ALOGE("StateTracker error extracting primary key from log event.");
- handleReset();
+ handleReset(eventTimeNs);
return;
}
} else {
- // atom has no primary fields
+ // Use an empty HashableDimensionKey if atom has no primary fields.
primaryKey = DEFAULT_DIMENSION_KEY;
}
- // parse event for state value
+ // Parse event for state value.
FieldValue stateValue;
int32_t state;
if (!filterValues(mStateField, event.getValues(), &stateValue) ||
stateValue.mValue.getType() != INT) {
ALOGE("StateTracker error extracting state from log event. Type: %d",
stateValue.mValue.getType());
- handlePartialReset(primaryKey);
+ handlePartialReset(eventTimeNs, primaryKey);
return;
}
state = stateValue.mValue.int_value;
if (state == mResetState) {
VLOG("StateTracker Reset state: %s", stateValue.mValue.toString().c_str());
- handleReset();
+ handleReset(eventTimeNs);
}
- // track and update state
+ // Track and update state.
int32_t oldState = 0;
int32_t newState = 0;
updateState(primaryKey, state, &oldState, &newState);
- // notify all listeners if state has changed
+ // Notify all listeners if state has changed.
if (oldState != newState) {
VLOG("StateTracker updated state");
for (auto listener : mListeners) {
auto sListener = listener.promote(); // safe access to wp<>
if (sListener != nullptr) {
- sListener->onStateChanged(mAtomId, primaryKey, oldState, newState);
+ sListener->onStateChanged(eventTimeNs, mAtomId, primaryKey, oldState, newState);
}
}
} else {
@@ -119,20 +121,22 @@
return false;
}
-void StateTracker::handleReset() {
+void StateTracker::handleReset(const int64_t eventTimeNs) {
VLOG("StateTracker handle reset");
for (const auto pair : mStateMap) {
for (auto l : mListeners) {
auto sl = l.promote();
if (sl != nullptr) {
- sl->onStateChanged(mAtomId, pair.first, pair.second.state, mDefaultState);
+ sl->onStateChanged(eventTimeNs, mAtomId, pair.first, pair.second.state,
+ mDefaultState);
}
}
}
mStateMap.clear();
}
-void StateTracker::handlePartialReset(const HashableDimensionKey& primaryKey) {
+void StateTracker::handlePartialReset(const int64_t eventTimeNs,
+ const HashableDimensionKey& primaryKey) {
VLOG("StateTracker handle partial reset");
if (mStateMap.find(primaryKey) != mStateMap.end()) {
mStateMap.erase(primaryKey);
diff --git a/cmds/statsd/src/state/StateTracker.h b/cmds/statsd/src/state/StateTracker.h
index 450412d..544857f 100644
--- a/cmds/statsd/src/state/StateTracker.h
+++ b/cmds/statsd/src/state/StateTracker.h
@@ -81,10 +81,10 @@
std::set<wp<StateListener>> mListeners;
// Reset all state values in map to default state
- void handleReset();
+ void handleReset(const int64_t eventTimeNs);
// Reset only the state value mapped to primary key to default state
- void handlePartialReset(const HashableDimensionKey& primaryKey);
+ void handlePartialReset(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey);
// Update the StateMap based on the received state value.
// Store the old and new states.
diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp
index 4208fef..395167b 100644
--- a/cmds/statsd/tests/state/StateTracker_test.cpp
+++ b/cmds/statsd/tests/state/StateTracker_test.cpp
@@ -44,8 +44,8 @@
std::vector<Update> updates;
- void onStateChanged(int atomId, const HashableDimensionKey& primaryKey, int oldState,
- int newState) {
+ void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
+ const HashableDimensionKey& primaryKey, int oldState, int newState) {
updates.emplace_back(primaryKey, newState);
}
};
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index 03b08f7..1987440 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -16,10 +16,12 @@
package com.android.commands.telecom;
+import android.app.ActivityThread;
import android.content.ComponentName;
import android.content.Context;
import android.net.Uri;
import android.os.IUserManager;
+import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -33,7 +35,6 @@
import com.android.internal.os.BaseCommand;
import com.android.internal.telecom.ITelecomService;
-import com.android.internal.telephony.ITelephony;
import java.io.PrintStream;
@@ -82,7 +83,7 @@
private ComponentName mComponent;
private String mAccountId;
private ITelecomService mTelecomService;
- private ITelephony mTelephonyService;
+ private TelephonyManager mTelephonyManager;
private IUserManager mUserManager;
@Override
@@ -153,9 +154,10 @@
return;
}
- mTelephonyService = ITelephony.Stub.asInterface(
- ServiceManager.getService(Context.TELEPHONY_SERVICE));
- if (mTelephonyService == null) {
+ Looper.prepareMainLooper();
+ Context context = ActivityThread.systemMain().getSystemContext();
+ mTelephonyManager = context.getSystemService(TelephonyManager.class);
+ if (mTelephonyManager == null) {
Log.w(this, "onRun: Can't access telephony service.");
showError("Error: Could not access the Telephony Service. Is the system running?");
return;
@@ -351,7 +353,7 @@
}
int numSims = Integer.parseInt(nextArgRequired());
System.out.println("Setting sim count to " + numSims + ". Device may reboot");
- mTelephonyService.switchMultiSimConfig(numSims);
+ mTelephonyManager.switchMultiSimConfig(numSims);
}
/**
@@ -365,8 +367,7 @@
private void runGetMaxPhones() throws RemoteException {
// This assumes the max number of SIMs is 2, which it currently is
- if (TelephonyManager.MULTISIM_ALLOWED
- == mTelephonyService.isMultiSimSupported("com.android.commands.telecom", null)) {
+ if (TelephonyManager.MULTISIM_ALLOWED == mTelephonyManager.isMultiSimSupported()) {
System.out.println("2");
} else {
System.out.println("1");
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 3db0b26..7fd01db 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -20,6 +20,8 @@
import android.annotation.IntDef;
import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
@@ -512,6 +514,21 @@
private static final long REQUEST_ACCESSIBILITY_BUTTON_CHANGE = 136293963L;
/**
+ * Resource id of the animated image of the accessibility service.
+ */
+ private int mAnimatedImageRes;
+
+ /**
+ * Resource id of the html description of the accessibility service.
+ */
+ private int mHtmlDescriptionRes;
+
+ /**
+ * Non localized html description of the accessibility service.
+ */
+ private String mNonLocalizedHtmlDescription;
+
+ /**
* Creates a new instance.
*/
public AccessibilityServiceInfo() {
@@ -626,6 +643,20 @@
mNonLocalizedSummary = nonLocalizedSummary.toString().trim();
}
}
+ peekedValue = asAttributes.peekValue(
+ com.android.internal.R.styleable.AccessibilityService_animatedImageDrawable);
+ if (peekedValue != null) {
+ mAnimatedImageRes = peekedValue.resourceId;
+ }
+ peekedValue = asAttributes.peekValue(
+ com.android.internal.R.styleable.AccessibilityService_htmlDescription);
+ if (peekedValue != null) {
+ mHtmlDescriptionRes = peekedValue.resourceId;
+ final CharSequence nonLocalizedHtmlDescription = peekedValue.coerceToString();
+ if (nonLocalizedHtmlDescription != null) {
+ mNonLocalizedHtmlDescription = nonLocalizedHtmlDescription.toString().trim();
+ }
+ }
asAttributes.recycle();
} catch (NameNotFoundException e) {
throw new XmlPullParserException( "Unable to create context for: "
@@ -727,6 +758,18 @@
}
/**
+ * The animated image resource id.
+ * <p>
+ * <strong>Statically set from
+ * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
+ * </p>
+ * @return The animated image resource id.
+ */
+ public int getAnimatedImageRes() {
+ return mAnimatedImageRes;
+ }
+
+ /**
* Whether this service can retrieve the current window's content.
* <p>
* <strong>Statically set from
@@ -833,6 +876,29 @@
}
/**
+ * The localized html description of the accessibility service.
+ * <p>
+ * <strong>Statically set from
+ * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
+ * </p>
+ * @return The localized html description.
+ */
+ @Nullable
+ public String loadHtmlDescription(@NonNull PackageManager packageManager) {
+ if (mHtmlDescriptionRes == 0) {
+ return mNonLocalizedHtmlDescription;
+ }
+
+ final ServiceInfo serviceInfo = mResolveInfo.serviceInfo;
+ final CharSequence htmlDescription = packageManager.getText(serviceInfo.packageName,
+ mHtmlDescriptionRes, serviceInfo.applicationInfo);
+ if (htmlDescription != null) {
+ return htmlDescription.toString().trim();
+ }
+ return null;
+ }
+
+ /**
* Set the recommended time that non-interactive controls need to remain on the screen to
* support the user.
* <p>
@@ -915,7 +981,10 @@
parcel.writeInt(mSummaryResId);
parcel.writeString(mNonLocalizedSummary);
parcel.writeInt(mDescriptionResId);
+ parcel.writeInt(mAnimatedImageRes);
+ parcel.writeInt(mHtmlDescriptionRes);
parcel.writeString(mNonLocalizedDescription);
+ parcel.writeString(mNonLocalizedHtmlDescription);
}
private void initFromParcel(Parcel parcel) {
@@ -934,7 +1003,10 @@
mSummaryResId = parcel.readInt();
mNonLocalizedSummary = parcel.readString();
mDescriptionResId = parcel.readInt();
+ mAnimatedImageRes = parcel.readInt();
+ mHtmlDescriptionRes = parcel.readInt();
mNonLocalizedDescription = parcel.readString();
+ mNonLocalizedHtmlDescription = parcel.readString();
}
@Override
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index 3a34b79..d8ddf218 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -1148,11 +1148,11 @@
};
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(AlarmClockInfoProto.TRIGGER_TIME_MS, mTriggerTime);
if (mShowIntent != null) {
- mShowIntent.writeToProto(proto, AlarmClockInfoProto.SHOW_INTENT);
+ mShowIntent.dumpDebug(proto, AlarmClockInfoProto.SHOW_INTENT);
}
proto.end(token);
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0113f69..034826a 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -39,6 +39,7 @@
import android.content.pm.IPackageManager;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
+import android.content.pm.InstallSourceInfo;
import android.content.pm.InstantAppInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.IntentFilterVerificationInfo;
@@ -2085,6 +2086,21 @@
}
@Override
+ @NonNull
+ public InstallSourceInfo getInstallSourceInfo(String packageName) throws NameNotFoundException {
+ final InstallSourceInfo installSourceInfo;
+ try {
+ installSourceInfo = mPM.getInstallSourceInfo(packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ if (installSourceInfo == null) {
+ throw new NameNotFoundException(packageName);
+ }
+ return installSourceInfo;
+ }
+
+ @Override
public int getMoveStatus(int moveId) {
try {
return mPM.getMoveStatus(moveId);
@@ -2782,7 +2798,7 @@
public Drawable loadUnbadgedItemIcon(@NonNull PackageItemInfo itemInfo,
@Nullable ApplicationInfo appInfo) {
if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
- // Indicates itemInfo is for a different user (e.g. a profile's parent), so use a
+ // Indicates itemInfo is for a different user (e.g. a profile's parent), so use a
// generic user icon (users generally lack permission to view each other's actual icons)
int targetUserId = itemInfo.showUserIcon;
return UserIcons.getDefaultUserIcon(
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 50d0dab..aa8a302 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -387,6 +387,7 @@
void requestInteractiveBugReport();
void requestFullBugReport();
void requestRemoteBugReport();
+ boolean launchBugReportHandlerApp();
@UnsupportedAppUsage
Intent getIntentForIntentSender(in IIntentSender sender);
diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java
index 11c747f..74fb99a 100644
--- a/core/java/android/app/IntentService.java
+++ b/core/java/android/app/IntentService.java
@@ -44,13 +44,6 @@
* long as necessary (and will not block the application's main loop), but
* only one request will be processed at a time.
*
- * <p class="note"><b>Note:</b> IntentService is subject to all the
- * <a href="/preview/features/background.html">background execution limits</a>
- * imposed with Android 8.0 (API level 26). In most cases, you are better off
- * using {@link android.support.v4.app.JobIntentService}, which uses jobs
- * instead of services when running on Android 8.0 or higher.
- * </p>
- *
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For a detailed discussion about how to create services, read the
@@ -59,8 +52,14 @@
* </div>
*
* @see android.support.v4.app.JobIntentService
- * @see android.os.AsyncTask
+ *
+ * @deprecated IntentService is subject to all the
+ * <a href="/preview/features/background.html">background execution limits</a>
+ * imposed with Android 8.0 (API level 26). Consider using {@link androidx.work.WorkManager}
+ * or {@link androidx.core.app.JobIntentService}, which uses jobs
+ * instead of services when running on Android 8.0 or higher.
*/
+@Deprecated
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
@UnsupportedAppUsage
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index b37cc26..e307142 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2977,7 +2977,7 @@
/**
* @hide
*/
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(NotificationProto.CHANNEL_ID, getChannelId());
proto.write(NotificationProto.HAS_TICKER_TEXT, this.tickerText != null);
@@ -2993,7 +2993,7 @@
proto.write(NotificationProto.VISIBILITY, this.visibility);
}
if (publicVersion != null) {
- publicVersion.writeToProto(proto, NotificationProto.PUBLIC_VERSION);
+ publicVersion.dumpDebug(proto, NotificationProto.PUBLIC_VERSION);
}
proto.end(token);
}
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 20d977b..1fc8a2b 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -1116,7 +1116,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(NotificationChannelProto.ID, mId);
@@ -1142,7 +1142,7 @@
proto.write(NotificationChannelProto.IS_DELETED, mDeleted);
proto.write(NotificationChannelProto.GROUP, mGroup);
if (mAudioAttributes != null) {
- mAudioAttributes.writeToProto(proto, NotificationChannelProto.AUDIO_ATTRIBUTES);
+ mAudioAttributes.dumpDebug(proto, NotificationChannelProto.AUDIO_ATTRIBUTES);
}
proto.write(NotificationChannelProto.IS_BLOCKABLE_SYSTEM, mBlockableSystem);
proto.write(NotificationChannelProto.ALLOW_APP_OVERLAY, mAllowBubbles);
diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java
index a8ee414..c4c1e4f 100644
--- a/core/java/android/app/NotificationChannelGroup.java
+++ b/core/java/android/app/NotificationChannelGroup.java
@@ -332,7 +332,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(NotificationChannelGroupProto.ID, mId);
@@ -340,7 +340,7 @@
proto.write(NotificationChannelGroupProto.DESCRIPTION, mDescription);
proto.write(NotificationChannelGroupProto.IS_BLOCKED, mBlocked);
for (NotificationChannel channel : mChannels) {
- channel.writeToProto(proto, NotificationChannelGroupProto.CHANNELS);
+ channel.dumpDebug(proto, NotificationChannelGroupProto.CHANNELS);
}
proto.end(token);
}
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 03ee1e9..850645d 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1855,7 +1855,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long pToken = proto.start(fieldId);
bitwiseToProtoEnum(proto, PolicyProto.PRIORITY_CATEGORIES, priorityCategories);
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 06b9506..0407a8a 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -1204,7 +1204,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
if (mTarget != null) {
proto.write(PendingIntentProto.TARGET, mTarget.asBinder().toString());
diff --git a/core/java/android/app/ProfilerInfo.java b/core/java/android/app/ProfilerInfo.java
index 25589f8..d6eb4a8 100644
--- a/core/java/android/app/ProfilerInfo.java
+++ b/core/java/android/app/ProfilerInfo.java
@@ -135,7 +135,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(ProfilerInfoProto.PROFILE_FILE, profileFile);
if (profileFd != null) {
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 1f91b3f..9b62e3b 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -57,7 +57,7 @@
* networking) operations, it should spawn its own thread in which to do that
* work. More information on this can be found in
* <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
- * Threads</a>. The {@link IntentService} class is available
+ * Threads</a>. The {@link androidx.core.app.JobIntentService} class is available
* as a standard implementation of Service that has its own thread where it
* schedules its work to be done.</p>
*
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 11d6528a..2ef0510 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -51,12 +51,13 @@
private static final String TAG = "StatsManager";
private static final boolean DEBUG = false;
+ private static final Object sLock = new Object();
private final Context mContext;
- @GuardedBy("this")
+ @GuardedBy("sLock")
private IStatsManager mService;
- @GuardedBy("this")
+ @GuardedBy("sLock")
private IStatsCompanionService mStatsCompanion;
/**
@@ -125,7 +126,7 @@
*/
@RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
public void addConfig(long configKey, byte[] config) throws StatsUnavailableException {
- synchronized (this) {
+ synchronized (sLock) {
try {
IStatsManager service = getIStatsManagerLocked();
// can throw IllegalArgumentException
@@ -162,7 +163,7 @@
*/
@RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
public void removeConfig(long configKey) throws StatsUnavailableException {
- synchronized (this) {
+ synchronized (sLock) {
try {
IStatsManager service = getIStatsManagerLocked();
service.removeConfiguration(configKey, mContext.getOpPackageName());
@@ -223,7 +224,7 @@
public void setBroadcastSubscriber(
PendingIntent pendingIntent, long configKey, long subscriberId)
throws StatsUnavailableException {
- synchronized (this) {
+ synchronized (sLock) {
try {
IStatsManager service = getIStatsManagerLocked();
if (pendingIntent != null) {
@@ -277,7 +278,7 @@
@RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
public void setFetchReportsOperation(PendingIntent pendingIntent, long configKey)
throws StatsUnavailableException {
- synchronized (this) {
+ synchronized (sLock) {
try {
IStatsManager service = getIStatsManagerLocked();
if (pendingIntent == null) {
@@ -315,7 +316,7 @@
@RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
public @NonNull long[] setActiveConfigsChangedOperation(@Nullable PendingIntent pendingIntent)
throws StatsUnavailableException {
- synchronized (this) {
+ synchronized (sLock) {
try {
IStatsManager service = getIStatsManagerLocked();
if (pendingIntent == null) {
@@ -363,7 +364,7 @@
*/
@RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
public byte[] getReports(long configKey) throws StatsUnavailableException {
- synchronized (this) {
+ synchronized (sLock) {
try {
IStatsManager service = getIStatsManagerLocked();
return service.getData(configKey, mContext.getOpPackageName());
@@ -400,7 +401,7 @@
*/
@RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
public byte[] getStatsMetadata() throws StatsUnavailableException {
- synchronized (this) {
+ synchronized (sLock) {
try {
IStatsManager service = getIStatsManagerLocked();
return service.getMetadata(mContext.getOpPackageName());
@@ -435,7 +436,7 @@
@RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
public long[] getRegisteredExperimentIds()
throws StatsUnavailableException {
- synchronized (this) {
+ synchronized (sLock) {
try {
IStatsManager service = getIStatsManagerLocked();
if (service == null) {
@@ -472,7 +473,7 @@
@RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
public void setPullerCallback(int atomTag, IStatsPullerCallback callback)
throws StatsUnavailableException {
- synchronized (this) {
+ synchronized (sLock) {
try {
IStatsManager service = getIStatsManagerLocked();
if (callback == null) {
@@ -515,7 +516,7 @@
if (additiveFields == null) {
additiveFields = new int[0];
}
- synchronized (this) {
+ synchronized (sLock) {
IStatsCompanionService service = getIStatsCompanionServiceLocked();
PullAtomCallbackInternal rec =
new PullAtomCallbackInternal(atomTag, callback, executor);
@@ -649,13 +650,13 @@
private class StatsdDeathRecipient implements IBinder.DeathRecipient {
@Override
public void binderDied() {
- synchronized (this) {
+ synchronized (sLock) {
mService = null;
}
}
}
- @GuardedBy("this")
+ @GuardedBy("sLock")
private IStatsManager getIStatsManagerLocked() throws StatsUnavailableException {
if (mService != null) {
return mService;
@@ -672,7 +673,7 @@
return mService;
}
- @GuardedBy("this")
+ @GuardedBy("sLock")
private IStatsCompanionService getIStatsCompanionServiceLocked() {
if (mStatsCompanion != null) {
return mStatsCompanion;
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 1829f74..601b658 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -1137,7 +1137,8 @@
registerService(Context.PERMISSION_SERVICE, PermissionManager.class,
new CachedServiceFetcher<PermissionManager>() {
@Override
- public PermissionManager createService(ContextImpl ctx) {
+ public PermissionManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
IPackageManager packageManager = AppGlobals.getPackageManager();
return new PermissionManager(ctx.getOuterContext(), packageManager);
}});
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index 8cb094f..aa6492e 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -615,15 +615,15 @@
* @param fieldId Field Id of the WindowConfiguration as defined in the parent message
* @hide
*/
- public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
+ public void dumpDebug(ProtoOutputStream protoOutputStream, long fieldId) {
final long token = protoOutputStream.start(fieldId);
if (mAppBounds != null) {
- mAppBounds.writeToProto(protoOutputStream, APP_BOUNDS);
+ mAppBounds.dumpDebug(protoOutputStream, APP_BOUNDS);
}
protoOutputStream.write(WINDOWING_MODE, mWindowingMode);
protoOutputStream.write(ACTIVITY_TYPE, mActivityType);
if (mBounds != null) {
- mBounds.writeToProto(protoOutputStream, BOUNDS);
+ mBounds.dumpDebug(protoOutputStream, BOUNDS);
}
protoOutputStream.end(token);
}
diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java
index 00903c4..63bc40b 100644
--- a/core/java/android/app/admin/DeviceAdminInfo.java
+++ b/core/java/android/app/admin/DeviceAdminInfo.java
@@ -55,6 +55,14 @@
static final String TAG = "DeviceAdminInfo";
/**
+ * A type of policy that this device admin can use: profile owner on an organization-owned
+ * device.
+ *
+ * @hide
+ */
+ public static final int USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER = -3;
+
+ /**
* A type of policy that this device admin can use: device owner meta-policy
* for an admin that is designated as owner of the device.
*
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 39dc51e..34ceb08 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -9135,7 +9135,14 @@
}
/**
- * Called by device owner to get the MAC address of the Wi-Fi device.
+ * Called by device owner, or profile owner on organization-owned device, to get the MAC
+ * address of the Wi-Fi device.
+ *
+ * NOTE: The MAC address returned here should only be used for inventory management and is
+ * not likely to be the MAC address used by the device to connect to Wi-Fi networks: MAC
+ * addresses used for scanning and connecting to Wi-Fi networks are randomized by default.
+ * To get the randomized MAC address used, call
+ * {@link android.net.wifi.WifiConfiguration#getRandomizedMacAddress}.
*
* @param admin Which device owner this request is associated with.
* @return the MAC address of the Wi-Fi device, or null when the information is not available.
diff --git a/core/java/android/app/timedetector/ManualTimeSuggestion.java b/core/java/android/app/timedetector/ManualTimeSuggestion.java
index e7d619a..471606da 100644
--- a/core/java/android/app/timedetector/ManualTimeSuggestion.java
+++ b/core/java/android/app/timedetector/ManualTimeSuggestion.java
@@ -85,7 +85,8 @@
@NonNull
public List<String> getDebugInfo() {
- return Collections.unmodifiableList(mDebugInfo);
+ return mDebugInfo == null
+ ? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo);
}
/**
diff --git a/core/java/android/app/timedetector/PhoneTimeSuggestion.java b/core/java/android/app/timedetector/PhoneTimeSuggestion.java
index 233dbbc..dd02af7 100644
--- a/core/java/android/app/timedetector/PhoneTimeSuggestion.java
+++ b/core/java/android/app/timedetector/PhoneTimeSuggestion.java
@@ -23,7 +23,6 @@
import android.util.TimestampedValue;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -52,20 +51,25 @@
};
private final int mPhoneId;
- @Nullable private TimestampedValue<Long> mUtcTime;
+ @Nullable private final TimestampedValue<Long> mUtcTime;
@Nullable private ArrayList<String> mDebugInfo;
- public PhoneTimeSuggestion(int phoneId) {
- mPhoneId = phoneId;
+ private PhoneTimeSuggestion(Builder builder) {
+ mPhoneId = builder.mPhoneId;
+ mUtcTime = builder.mUtcTime;
+ mDebugInfo = builder.mDebugInfo != null ? new ArrayList<>(builder.mDebugInfo) : null;
}
private static PhoneTimeSuggestion createFromParcel(Parcel in) {
int phoneId = in.readInt();
- PhoneTimeSuggestion suggestion = new PhoneTimeSuggestion(phoneId);
- suggestion.setUtcTime(in.readParcelable(null /* classLoader */));
+ PhoneTimeSuggestion suggestion = new PhoneTimeSuggestion.Builder(phoneId)
+ .setUtcTime(in.readParcelable(null /* classLoader */))
+ .build();
@SuppressWarnings("unchecked")
ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
- suggestion.mDebugInfo = debugInfo;
+ if (debugInfo != null) {
+ suggestion.addDebugInfo(debugInfo);
+ }
return suggestion;
}
@@ -85,10 +89,6 @@
return mPhoneId;
}
- public void setUtcTime(@Nullable TimestampedValue<Long> utcTime) {
- mUtcTime = utcTime;
- }
-
@Nullable
public TimestampedValue<Long> getUtcTime() {
return mUtcTime;
@@ -96,7 +96,8 @@
@NonNull
public List<String> getDebugInfo() {
- return Collections.unmodifiableList(mDebugInfo);
+ return mDebugInfo == null
+ ? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo);
}
/**
@@ -104,11 +105,23 @@
* information is present in {@link #toString()} but is not considered for
* {@link #equals(Object)} and {@link #hashCode()}.
*/
- public void addDebugInfo(String... debugInfos) {
+ public void addDebugInfo(String debugInfo) {
if (mDebugInfo == null) {
mDebugInfo = new ArrayList<>();
}
- mDebugInfo.addAll(Arrays.asList(debugInfos));
+ mDebugInfo.add(debugInfo);
+ }
+
+ /**
+ * Associates information with the instance that can be useful for debugging / logging. The
+ * information is present in {@link #toString()} but is not considered for
+ * {@link #equals(Object)} and {@link #hashCode()}.
+ */
+ public void addDebugInfo(@NonNull List<String> debugInfo) {
+ if (mDebugInfo == null) {
+ mDebugInfo = new ArrayList<>(debugInfo.size());
+ }
+ mDebugInfo.addAll(debugInfo);
}
@Override
@@ -137,4 +150,39 @@
+ ", mDebugInfo=" + mDebugInfo
+ '}';
}
+
+ /**
+ * Builds {@link PhoneTimeSuggestion} instances.
+ *
+ * @hide
+ */
+ public static class Builder {
+ private final int mPhoneId;
+ private TimestampedValue<Long> mUtcTime;
+ private List<String> mDebugInfo;
+
+ public Builder(int phoneId) {
+ mPhoneId = phoneId;
+ }
+
+ /** Returns the builder for call chaining. */
+ public Builder setUtcTime(TimestampedValue<Long> utcTime) {
+ mUtcTime = utcTime;
+ return this;
+ }
+
+ /** Returns the builder for call chaining. */
+ public Builder addDebugInfo(@NonNull String debugInfo) {
+ if (mDebugInfo == null) {
+ mDebugInfo = new ArrayList<>();
+ }
+ mDebugInfo.add(debugInfo);
+ return this;
+ }
+
+ /** Returns the {@link PhoneTimeSuggestion}. */
+ public PhoneTimeSuggestion build() {
+ return new PhoneTimeSuggestion(this);
+ }
+ }
}
diff --git a/core/java/android/app/timezonedetector/TimeZoneDetector.java b/core/java/android/app/timezonedetector/TimeZoneDetector.java
index 909cbc2..387a36b 100644
--- a/core/java/android/app/timezonedetector/TimeZoneDetector.java
+++ b/core/java/android/app/timezonedetector/TimeZoneDetector.java
@@ -17,6 +17,7 @@
package android.app.timezonedetector;
import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.content.Context;
import android.os.RemoteException;
@@ -26,10 +27,11 @@
/**
* The interface through which system components can send signals to the TimeZoneDetectorService.
+ *
* @hide
*/
@SystemService(Context.TIME_ZONE_DETECTOR_SERVICE)
-public final class TimeZoneDetector {
+public class TimeZoneDetector {
private static final String TAG = "timezonedetector.TimeZoneDetector";
private static final boolean DEBUG = false;
@@ -41,10 +43,11 @@
}
/**
- * Suggests the current time zone to the detector. The detector may ignore the signal if better
- * signals are available such as those that come from more reliable sources or were
- * determined more recently.
+ * Suggests the current time zone, determined using telephony signals, to the detector. The
+ * detector may ignore the signal based on system settings, whether better information is
+ * available, and so on.
*/
+ @RequiresPermission(android.Manifest.permission.SET_TIME_ZONE)
public void suggestPhoneTimeZone(@NonNull PhoneTimeZoneSuggestion timeZoneSuggestion) {
if (DEBUG) {
Log.d(TAG, "suggestPhoneTimeZone called: " + timeZoneSuggestion);
@@ -56,4 +59,28 @@
}
}
+ /**
+ * Suggests the current time zone, determined for the user's manually information, to the
+ * detector. The detector may ignore the signal based on system settings.
+ */
+ @RequiresPermission(android.Manifest.permission.SET_TIME_ZONE)
+ public void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion) {
+ if (DEBUG) {
+ Log.d(TAG, "suggestManualTimeZone called: " + timeZoneSuggestion);
+ }
+ try {
+ mITimeZoneDetectorService.suggestManualTimeZone(timeZoneSuggestion);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * A shared utility method to create a {@link ManualTimeZoneSuggestion}.
+ */
+ public static ManualTimeZoneSuggestion createManualTimeZoneSuggestion(String tzId, String why) {
+ ManualTimeZoneSuggestion suggestion = new ManualTimeZoneSuggestion(tzId);
+ suggestion.addDebugInfo(why);
+ return suggestion;
+ }
}
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index accdd8d..8ed61b6 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -610,7 +610,7 @@
if (uuids == null) return false;
for (ParcelUuid uuid : uuids) {
- if (BluetoothUuid.isAvrcpTarget(uuid)) {
+ if (uuid.equals(BluetoothUuid.AVRCP_TARGET)) {
return true;
}
}
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index ea3831a..0955b10 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -559,7 +559,7 @@
*
* <p> The device should already be paired.
* Priority can be one of {@link BluetoothProfile#PRIORITY_ON} or
- * {@link BluetoothProfile#PRIORITY_OFF},
+ * {@link BluetoothProfile#PRIORITY_OFF}
*
* @param device Paired bluetooth device
* @param priority
@@ -1133,8 +1133,9 @@
* is active.
* @hide
*/
+ @SystemApi
+ @Nullable
@RequiresPermission(android.Manifest.permission.BLUETOOTH)
- @UnsupportedAppUsage
public BluetoothDevice getActiveDevice() {
if (VDBG) {
Log.d(TAG, "getActiveDevice");
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index a8e1fd2..7ee29ff 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -557,7 +557,7 @@
* Set priority of the profile
*
* <p> The device should already be paired.
- * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
+ * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF}
*
* @param device Paired bluetooth device
* @param priority
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index bc3c9a9..7e96c23 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -16,8 +16,10 @@
package android.bluetooth;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
-import android.os.Build;
import android.os.ParcelUuid;
import java.nio.ByteBuffer;
@@ -31,6 +33,7 @@
*
* @hide
*/
+@SystemApi
public final class BluetoothUuid {
/* See Bluetooth Assigned Numbers document - SDP section, to get the values of UUIDs
@@ -39,167 +42,157 @@
* The following 128 bit values are calculated as:
* uuid * 2^96 + BASE_UUID
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public static final ParcelUuid AudioSink =
+
+ /** @hide */
+ @NonNull
+ @SystemApi
+ public static final ParcelUuid A2DP_SINK =
ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
- public static final ParcelUuid AudioSource =
+ /** @hide */
+ @NonNull
+ @SystemApi
+ public static final ParcelUuid A2DP_SOURCE =
ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public static final ParcelUuid AdvAudioDist =
+ /** @hide */
+ @NonNull
+ @SystemApi
+ public static final ParcelUuid ADV_AUDIO_DIST =
ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB");
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid HSP =
ParcelUuid.fromString("00001108-0000-1000-8000-00805F9B34FB");
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid HSP_AG =
ParcelUuid.fromString("00001112-0000-1000-8000-00805F9B34FB");
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public static final ParcelUuid Handsfree =
+ /** @hide */
+ @NonNull
+ @SystemApi
+ public static final ParcelUuid HFP =
ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB");
- public static final ParcelUuid Handsfree_AG =
+ /** @hide */
+ @NonNull
+ @SystemApi
+ public static final ParcelUuid HFP_AG =
ParcelUuid.fromString("0000111F-0000-1000-8000-00805F9B34FB");
- public static final ParcelUuid AvrcpController =
+ /** @hide */
+ @NonNull
+ @SystemApi
+ public static final ParcelUuid AVRCP_CONTROLLER =
ParcelUuid.fromString("0000110E-0000-1000-8000-00805F9B34FB");
- public static final ParcelUuid AvrcpTarget =
+ /** @hide */
+ @NonNull
+ @SystemApi
+ public static final ParcelUuid AVRCP_TARGET =
ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB");
- @UnsupportedAppUsage
- public static final ParcelUuid ObexObjectPush =
+ /** @hide */
+ @NonNull
+ @SystemApi
+ public static final ParcelUuid OBEX_OBJECT_PUSH =
ParcelUuid.fromString("00001105-0000-1000-8000-00805f9b34fb");
- public static final ParcelUuid Hid =
+ /** @hide */
+ @NonNull
+ @SystemApi
+ public static final ParcelUuid HID =
ParcelUuid.fromString("00001124-0000-1000-8000-00805f9b34fb");
- @UnsupportedAppUsage
- public static final ParcelUuid Hogp =
+ /** @hide */
+ @NonNull
+ @SystemApi
+ public static final ParcelUuid HOGP =
ParcelUuid.fromString("00001812-0000-1000-8000-00805f9b34fb");
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid PANU =
ParcelUuid.fromString("00001115-0000-1000-8000-00805F9B34FB");
- @UnsupportedAppUsage
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid NAP =
ParcelUuid.fromString("00001116-0000-1000-8000-00805F9B34FB");
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid BNEP =
ParcelUuid.fromString("0000000f-0000-1000-8000-00805F9B34FB");
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid PBAP_PCE =
ParcelUuid.fromString("0000112e-0000-1000-8000-00805F9B34FB");
- @UnsupportedAppUsage
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid PBAP_PSE =
ParcelUuid.fromString("0000112f-0000-1000-8000-00805F9B34FB");
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid MAP =
ParcelUuid.fromString("00001134-0000-1000-8000-00805F9B34FB");
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid MNS =
ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB");
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid MAS =
ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB");
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid SAP =
ParcelUuid.fromString("0000112D-0000-1000-8000-00805F9B34FB");
- public static final ParcelUuid HearingAid =
+ /** @hide */
+ @NonNull
+ @SystemApi
+ public static final ParcelUuid HEARING_AID =
ParcelUuid.fromString("0000FDF0-0000-1000-8000-00805f9b34fb");
+ /** @hide */
+ @NonNull
+ @SystemApi
public static final ParcelUuid BASE_UUID =
ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
- /** Length of bytes for 16 bit UUID */
- public static final int UUID_BYTES_16_BIT = 2;
- /** Length of bytes for 32 bit UUID */
- public static final int UUID_BYTES_32_BIT = 4;
- /** Length of bytes for 128 bit UUID */
- public static final int UUID_BYTES_128_BIT = 16;
-
- @UnsupportedAppUsage
- public static final ParcelUuid[] RESERVED_UUIDS = {
- AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
- ObexObjectPush, PANU, NAP, MAP, MNS, MAS, SAP};
-
- @UnsupportedAppUsage
- public static boolean isAudioSource(ParcelUuid uuid) {
- return uuid.equals(AudioSource);
- }
-
- public static boolean isAudioSink(ParcelUuid uuid) {
- return uuid.equals(AudioSink);
- }
-
- @UnsupportedAppUsage
- public static boolean isAdvAudioDist(ParcelUuid uuid) {
- return uuid.equals(AdvAudioDist);
- }
-
- public static boolean isHandsfree(ParcelUuid uuid) {
- return uuid.equals(Handsfree);
- }
-
- public static boolean isHeadset(ParcelUuid uuid) {
- return uuid.equals(HSP);
- }
-
- public static boolean isAvrcpController(ParcelUuid uuid) {
- return uuid.equals(AvrcpController);
- }
-
- @UnsupportedAppUsage
- public static boolean isAvrcpTarget(ParcelUuid uuid) {
- return uuid.equals(AvrcpTarget);
- }
-
- public static boolean isInputDevice(ParcelUuid uuid) {
- return uuid.equals(Hid);
- }
-
- public static boolean isPanu(ParcelUuid uuid) {
- return uuid.equals(PANU);
- }
-
- public static boolean isNap(ParcelUuid uuid) {
- return uuid.equals(NAP);
- }
-
- public static boolean isBnep(ParcelUuid uuid) {
- return uuid.equals(BNEP);
- }
-
- public static boolean isMap(ParcelUuid uuid) {
- return uuid.equals(MAP);
- }
-
- public static boolean isMns(ParcelUuid uuid) {
- return uuid.equals(MNS);
- }
-
- public static boolean isMas(ParcelUuid uuid) {
- return uuid.equals(MAS);
- }
-
- public static boolean isSap(ParcelUuid uuid) {
- return uuid.equals(SAP);
- }
-
/**
- * Returns true if ParcelUuid is present in uuidArray
+ * Length of bytes for 16 bit UUID
*
- * @param uuidArray - Array of ParcelUuids
- * @param uuid
+ * @hide
*/
- @UnsupportedAppUsage
- public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) {
- if ((uuidArray == null || uuidArray.length == 0) && uuid == null) {
- return true;
- }
-
- if (uuidArray == null) {
- return false;
- }
-
- for (ParcelUuid element : uuidArray) {
- if (element.equals(uuid)) return true;
- }
- return false;
- }
+ @SystemApi
+ public static final int UUID_BYTES_16_BIT = 2;
+ /**
+ * Length of bytes for 32 bit UUID
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int UUID_BYTES_32_BIT = 4;
+ /**
+ * Length of bytes for 128 bit UUID
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int UUID_BYTES_128_BIT = 16;
/**
* Returns true if there any common ParcelUuids in uuidA and uuidB.
*
* @param uuidA - List of ParcelUuids
* @param uuidB - List of ParcelUuids
+ *
+ * @hide
*/
- @UnsupportedAppUsage
- public static boolean containsAnyUuid(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
+ @SystemApi
+ public static boolean containsAnyUuid(@Nullable ParcelUuid[] uuidA,
+ @Nullable ParcelUuid[] uuidB) {
if (uuidA == null && uuidB == null) return true;
if (uuidA == null) {
@@ -218,29 +211,6 @@
}
/**
- * Returns true if all the ParcelUuids in ParcelUuidB are present in
- * ParcelUuidA
- *
- * @param uuidA - Array of ParcelUuidsA
- * @param uuidB - Array of ParcelUuidsB
- */
- public static boolean containsAllUuids(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
- if (uuidA == null && uuidB == null) return true;
-
- if (uuidA == null) {
- return uuidB.length == 0;
- }
-
- if (uuidB == null) return true;
-
- HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid>(Arrays.asList(uuidA));
- for (ParcelUuid uuid : uuidB) {
- if (!uuidSet.contains(uuid)) return false;
- }
- return true;
- }
-
- /**
* Extract the Service Identifier or the actual uuid from the Parcel Uuid.
* For example, if 0000110B-0000-1000-8000-00805F9B34FB is the parcel Uuid,
* this function will return 110B
@@ -248,7 +218,7 @@
* @param parcelUuid
* @return the service identifier.
*/
- public static int getServiceIdentifierFromParcelUuid(ParcelUuid parcelUuid) {
+ private static int getServiceIdentifierFromParcelUuid(ParcelUuid parcelUuid) {
UUID uuid = parcelUuid.getUuid();
long value = (uuid.getMostSignificantBits() & 0xFFFFFFFF00000000L) >>> 32;
return (int) value;
@@ -262,8 +232,12 @@
* @param uuidBytes Byte representation of uuid.
* @return {@link ParcelUuid} parsed from bytes.
* @throws IllegalArgumentException If the {@code uuidBytes} cannot be parsed.
+ *
+ * @hide
*/
- public static ParcelUuid parseUuidFrom(byte[] uuidBytes) {
+ @NonNull
+ @SystemApi
+ public static ParcelUuid parseUuidFrom(@Nullable byte[] uuidBytes) {
if (uuidBytes == null) {
throw new IllegalArgumentException("uuidBytes cannot be null");
}
@@ -305,6 +279,8 @@
* @param uuid uuid to parse.
* @return shortest representation of {@code uuid} as bytes.
* @throws IllegalArgumentException If the {@code uuid} is null.
+ *
+ * @hide
*/
public static byte[] uuidToBytes(ParcelUuid uuid) {
if (uuid == null) {
@@ -345,6 +321,8 @@
*
* @param parcelUuid
* @return true if the parcelUuid can be converted to 16 bit uuid, false otherwise.
+ *
+ * @hide
*/
@UnsupportedAppUsage
public static boolean is16BitUuid(ParcelUuid parcelUuid) {
@@ -361,6 +339,8 @@
*
* @param parcelUuid
* @return true if the parcelUuid can be converted to 32 bit uuid, false otherwise.
+ *
+ * @hide
*/
@UnsupportedAppUsage
public static boolean is32BitUuid(ParcelUuid parcelUuid) {
@@ -373,4 +353,6 @@
}
return ((uuid.getMostSignificantBits() & 0xFFFFFFFFL) == 0x1000L);
}
+
+ private BluetoothUuid() {}
}
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index b6a0a56..999ec37 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -682,7 +682,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
if (mHtmlText != null) {
@@ -692,7 +692,7 @@
} else if (mUri != null) {
proto.write(ClipDataProto.Item.URI, mUri.toString());
} else if (mIntent != null) {
- mIntent.writeToProto(proto, ClipDataProto.Item.INTENT, true, true, true, true);
+ mIntent.dumpDebug(proto, ClipDataProto.Item.INTENT, true, true, true, true);
} else {
proto.write(ClipDataProto.Item.NOTHING, true);
}
@@ -1076,11 +1076,11 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
if (mClipDescription != null) {
- mClipDescription.writeToProto(proto, ClipDataProto.DESCRIPTION);
+ mClipDescription.dumpDebug(proto, ClipDataProto.DESCRIPTION);
}
if (mIcon != null) {
final long iToken = proto.start(ClipDataProto.ICON);
@@ -1089,7 +1089,7 @@
proto.end(iToken);
}
for (int i = 0; i < mItems.size(); i++) {
- mItems.get(i).writeToProto(proto, ClipDataProto.ITEMS);
+ mItems.get(i).dumpDebug(proto, ClipDataProto.ITEMS);
}
proto.end(token);
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index 0c6a935..6739138 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -349,7 +349,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
final int size = mMimeTypes.size();
@@ -361,7 +361,7 @@
proto.write(ClipDescriptionProto.LABEL, mLabel.toString());
}
if (mExtras != null) {
- mExtras.writeToProto(proto, ClipDescriptionProto.EXTRAS);
+ mExtras.dumpDebug(proto, ClipDescriptionProto.EXTRAS);
}
if (mTimeStamp > 0) {
proto.write(ClipDescriptionProto.TIMESTAMP_MS, mTimeStamp);
diff --git a/core/java/android/content/ComponentName.java b/core/java/android/content/ComponentName.java
index 18147b5..33216d7 100644
--- a/core/java/android/content/ComponentName.java
+++ b/core/java/android/content/ComponentName.java
@@ -298,7 +298,7 @@
}
/** Put this here so that individual services don't have to reimplement this. @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(ComponentNameProto.PACKAGE_NAME, mPackage);
proto.write(ComponentNameProto.CLASS_NAME, mClass);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 341b520..d370a38 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3427,7 +3427,6 @@
//@hide: TIME_DETECTOR_SERVICE,
//@hide: TIME_ZONE_DETECTOR_SERVICE,
PERMISSION_SERVICE,
- INCREMENTAL_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ServiceName {}
@@ -4971,6 +4970,13 @@
/**
* Use with {@link #getSystemService(String)} to retrieve an
+ * {@link android.content.pm.DataLoaderManager}.
+ * @hide
+ */
+ public static final String DATA_LOADER_MANAGER_SERVICE = "dataloadermanager";
+
+ /**
+ * Use with {@link #getSystemService(String)} to retrieve an
* {@link android.os.incremental.IncrementalManager}.
* @hide
*/
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 40aca0e..7815a33 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -4053,6 +4053,13 @@
public static final String ACTION_SERVICE_STATE = "android.intent.action.SERVICE_STATE";
/**
+ * Used for looking up a Data Loader Service providers.
+ * @hide
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String ACTION_LOAD_DATA = "android.intent.action.LOAD_DATA";
+
+ /**
* An int extra used with {@link #ACTION_SERVICE_STATE} which indicates voice registration
* state.
* @see android.telephony.ServiceState#STATE_EMERGENCY_ONLY
@@ -10286,26 +10293,26 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
// Same input parameters that toString() gives to toShortString().
- writeToProto(proto, fieldId, true, true, true, false);
+ dumpDebug(proto, fieldId, true, true, true, false);
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto) {
+ public void dumpDebug(ProtoOutputStream proto) {
// Same input parameters that toString() gives to toShortString().
- writeToProtoWithoutFieldId(proto, true, true, true, false);
+ dumpDebugWithoutFieldId(proto, true, true, true, false);
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId, boolean secure, boolean comp,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, boolean secure, boolean comp,
boolean extras, boolean clip) {
long token = proto.start(fieldId);
- writeToProtoWithoutFieldId(proto, secure, comp, extras, clip);
+ dumpDebugWithoutFieldId(proto, secure, comp, extras, clip);
proto.end(token);
}
- private void writeToProtoWithoutFieldId(ProtoOutputStream proto, boolean secure, boolean comp,
+ private void dumpDebugWithoutFieldId(ProtoOutputStream proto, boolean secure, boolean comp,
boolean extras, boolean clip) {
if (mAction != null) {
proto.write(IntentProto.ACTION, mAction);
@@ -10331,7 +10338,7 @@
proto.write(IntentProto.PACKAGE, mPackage);
}
if (comp && mComponent != null) {
- mComponent.writeToProto(proto, IntentProto.COMPONENT);
+ mComponent.dumpDebug(proto, IntentProto.COMPONENT);
}
if (mSourceBounds != null) {
proto.write(IntentProto.SOURCE_BOUNDS, mSourceBounds.toShortString());
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 099dea2..93390bd 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -924,7 +924,7 @@
dest.writeInt(mPort);
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
// The original host information is already contained in host and wild, no output now.
proto.write(AuthorityEntryProto.HOST, mHost);
@@ -1758,7 +1758,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
if (mActions.size() > 0) {
Iterator<String> it = mActions.iterator();
@@ -1781,19 +1781,19 @@
if (mDataSchemeSpecificParts != null) {
Iterator<PatternMatcher> it = mDataSchemeSpecificParts.iterator();
while (it.hasNext()) {
- it.next().writeToProto(proto, IntentFilterProto.DATA_SCHEME_SPECS);
+ it.next().dumpDebug(proto, IntentFilterProto.DATA_SCHEME_SPECS);
}
}
if (mDataAuthorities != null) {
Iterator<AuthorityEntry> it = mDataAuthorities.iterator();
while (it.hasNext()) {
- it.next().writeToProto(proto, IntentFilterProto.DATA_AUTHORITIES);
+ it.next().dumpDebug(proto, IntentFilterProto.DATA_AUTHORITIES);
}
}
if (mDataPaths != null) {
Iterator<PatternMatcher> it = mDataPaths.iterator();
while (it.hasNext()) {
- it.next().writeToProto(proto, IntentFilterProto.DATA_PATHS);
+ it.next().dumpDebug(proto, IntentFilterProto.DATA_PATHS);
}
}
if (mDataTypes != null) {
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 37c6f57..552c8ac 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1398,9 +1398,9 @@
}
/** {@hide} */
- public void writeToProto(ProtoOutputStream proto, long fieldId, int dumpFlags) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, int dumpFlags) {
long token = proto.start(fieldId);
- super.writeToProto(proto, ApplicationInfoProto.PACKAGE, dumpFlags);
+ super.dumpDebug(proto, ApplicationInfoProto.PACKAGE, dumpFlags);
proto.write(ApplicationInfoProto.PERMISSION, permission);
proto.write(ApplicationInfoProto.PROCESS_NAME, processName);
proto.write(ApplicationInfoProto.UID, uid);
diff --git a/core/java/android/content/pm/DataLoaderManager.java b/core/java/android/content/pm/DataLoaderManager.java
new file mode 100644
index 0000000..2688038
--- /dev/null
+++ b/core/java/android/content/pm/DataLoaderManager.java
@@ -0,0 +1,87 @@
+/*
+ * 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 android.content.pm;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+/**
+ * Data loader manager takes care of data loaders of different packages. It provides methods to
+ * initialize a data loader binder service (binding and creating it), to return a binder of the data
+ * loader binder service and to destroy a data loader binder service.
+ * @see com.android.server.pm.DataLoaderManagerService
+ * @hide
+ */
+public class DataLoaderManager {
+ private static final String TAG = "DataLoaderManager";
+ private final IDataLoaderManager mService;
+
+ public DataLoaderManager(IDataLoaderManager service) {
+ mService = service;
+ }
+
+ /**
+ * Finds a data loader binder service and binds to it. This requires PackageManager.
+ *
+ * @param dataLoaderId ID for the new data loader binder service.
+ * @param params Bundle that contains parameters to configure the data loader service.
+ * Must contain:
+ * key: "packageName", value: String, package name of data loader service
+ * package;
+ * key: "extras", value: Bundle, client-specific data structures
+ *
+ * @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 Bundle params,
+ @NonNull IDataLoaderStatusListener listener) {
+ try {
+ return mService.initializeDataLoader(dataLoaderId, params, listener);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns a binder interface of the data loader binder service, given its ID.
+ */
+ @Nullable
+ public IDataLoader getDataLoader(int dataLoaderId) {
+ try {
+ return mService.getDataLoader(dataLoaderId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Destroys the data loader binder service and removes it from data loader manager service.
+ */
+ @Nullable
+ public void destroyDataLoader(int dataLoaderId) {
+ try {
+ mService.destroyDataLoader(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 dc576e8..9f3ab77 100644
--- a/core/java/android/content/pm/FeatureInfo.java
+++ b/core/java/android/content/pm/FeatureInfo.java
@@ -115,7 +115,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
if (name != null) {
proto.write(FeatureInfoProto.NAME, name);
diff --git a/core/java/android/content/pm/IDataLoader.aidl b/core/java/android/content/pm/IDataLoader.aidl
new file mode 100644
index 0000000..60cc9ba9
--- /dev/null
+++ b/core/java/android/content/pm/IDataLoader.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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 android.content.pm;
+
+import android.os.Bundle;
+import android.content.pm.IDataLoaderStatusListener;
+import android.content.pm.InstallationFile;
+import java.util.List;
+
+/**
+ * TODO: update with new APIs
+ * @hide
+ */
+oneway interface IDataLoader {
+ void create(int id, in Bundle params, IDataLoaderStatusListener listener);
+ void start(in List<InstallationFile> fileInfos);
+ void stop();
+ void destroy();
+ void onFileCreated(long inode, in byte[] metadata);
+}
diff --git a/core/java/android/content/pm/IDataLoaderManager.aidl b/core/java/android/content/pm/IDataLoaderManager.aidl
new file mode 100644
index 0000000..f453c9b
--- /dev/null
+++ b/core/java/android/content/pm/IDataLoaderManager.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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 android.content.pm;
+
+import android.os.Bundle;
+import android.content.pm.IDataLoader;
+import android.content.pm.IDataLoaderStatusListener;
+import java.util.List;
+
+/** @hide */
+interface IDataLoaderManager {
+ boolean initializeDataLoader(int id, in Bundle params, IDataLoaderStatusListener listener);
+ IDataLoader getDataLoader(int dataLoaderId);
+ void destroyDataLoader(int dataLoaderId);
+}
\ No newline at end of file
diff --git a/core/java/android/service/incremental/IIncrementalDataLoaderStatusListener.aidl b/core/java/android/content/pm/IDataLoaderStatusListener.aidl
similarity index 80%
rename from core/java/android/service/incremental/IIncrementalDataLoaderStatusListener.aidl
rename to core/java/android/content/pm/IDataLoaderStatusListener.aidl
index f04242d..a60d6ee 100644
--- a/core/java/android/service/incremental/IIncrementalDataLoaderStatusListener.aidl
+++ b/core/java/android/content/pm/IDataLoaderStatusListener.aidl
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package android.service.incremental;
+package android.content.pm;
/**
- * Callbacks from DataLoaderService to IncrementalService to report data loader status.
+ * Callbacks from a data loader binder service to report data loader status.
* @hide
*/
-oneway interface IIncrementalDataLoaderStatusListener {
+oneway interface IDataLoaderStatusListener {
/** Data loader status */
const int DATA_LOADER_READY = 0;
const int DATA_LOADER_NOT_READY = 1;
@@ -31,6 +31,6 @@
const int DATA_LOADER_CONNECTION_OK = 6;
/** Data loader status callback */
- void onStatusChanged(in int storageId, in int status);
+ void onStatusChanged(in int dataLoaderId, in int status);
}
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index b740617..0b3c765 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -46,4 +46,5 @@
int getParentSessionId();
boolean isStaged();
+ void addFile(in String name, long size, in byte[] metadata);
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index a71367d..b3d8eb5 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -26,6 +26,7 @@
import android.content.pm.InstantAppInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.IDexModuleRegisterCallback;
+import android.content.pm.InstallSourceInfo;
import android.content.pm.IPackageInstaller;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageDeleteObserver2;
@@ -237,6 +238,8 @@
@UnsupportedAppUsage
String getInstallerPackageName(in String packageName);
+ InstallSourceInfo getInstallSourceInfo(in String packageName);
+
void resetApplicationPreferences(int userId);
@UnsupportedAppUsage
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/content/pm/InstallSourceInfo.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/content/pm/InstallSourceInfo.aidl
index 007ec94..21ee4c3 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/content/pm/InstallSourceInfo.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * Copyright 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
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.content.pm;
-parcelable WifiActivityEnergyInfo;
+parcelable InstallSourceInfo;
diff --git a/core/java/android/content/pm/InstallSourceInfo.java b/core/java/android/content/pm/InstallSourceInfo.java
new file mode 100644
index 0000000..4d235f1
--- /dev/null
+++ b/core/java/android/content/pm/InstallSourceInfo.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 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 android.content.pm;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information about how an app was installed.
+ * @see PackageManager#getInstallSourceInfo(String)
+ */
+public final class InstallSourceInfo implements Parcelable {
+
+ @Nullable private final String mInitiatingPackageName;
+
+ @Nullable private final String mOriginatingPackageName;
+
+ @Nullable private final String mInstallingPackageName;
+
+ /** @hide */
+ public InstallSourceInfo(@Nullable String initiatingPackageName,
+ @Nullable String originatingPackageName, @Nullable String installingPackageName) {
+ this.mInitiatingPackageName = initiatingPackageName;
+ this.mOriginatingPackageName = originatingPackageName;
+ this.mInstallingPackageName = installingPackageName;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mInitiatingPackageName);
+ dest.writeString(mOriginatingPackageName);
+ dest.writeString(mInstallingPackageName);
+ }
+
+ private InstallSourceInfo(Parcel source) {
+ mInitiatingPackageName = source.readString();
+ mOriginatingPackageName = source.readString();
+ mInstallingPackageName = source.readString();
+ }
+
+ /** The name of the package that requested the installation, or null if not available. */
+ @Nullable
+ public String getInitiatingPackageName() {
+ return mInitiatingPackageName;
+ }
+
+ /**
+ * The name of the package on behalf of which the initiating package requested the installation,
+ * or null if not available.
+ * <p>
+ * For example if a downloaded APK is installed via the Package Installer this could be the
+ * app that performed the download. This value is provided by the initiating package and not
+ * verified by the framework.
+ * <p>
+ * Note that the {@code InstallSourceInfo} returned by
+ * {@link PackageManager#getInstallSourceInfo(String)} will not have this information
+ * available unless the calling application holds the INSTALL_PACKAGES permission.
+ */
+ @Nullable
+ public String getOriginatingPackageName() {
+ return mOriginatingPackageName;
+ }
+
+ /**
+ * The name of the package responsible for the installation (the installer of record), or null
+ * if not available.
+ * Note that this may differ from the initiating package name and can be modified.
+ *
+ * @see PackageManager#setInstallerPackageName(String, String)
+ */
+ @Nullable
+ public String getInstallingPackageName() {
+ return mInstallingPackageName;
+ }
+
+ @NonNull
+ public static final Parcelable.Creator<InstallSourceInfo> CREATOR =
+ new Creator<InstallSourceInfo>() {
+ @Override
+ public InstallSourceInfo createFromParcel(Parcel source) {
+ return new InstallSourceInfo(source);
+ }
+
+ @Override
+ public InstallSourceInfo[] newArray(int size) {
+ return new InstallSourceInfo[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/content/pm/InstallationFile.aidl
similarity index 68%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/content/pm/InstallationFile.aidl
index 007ec94..1edff9d 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/content/pm/InstallationFile.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,10 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.content.pm;
-parcelable WifiActivityEnergyInfo;
+/**
+ * Describes a file which is part of a package installation.
+ */
+parcelable InstallationFile;
+
diff --git a/core/java/android/content/pm/InstallationFile.java b/core/java/android/content/pm/InstallationFile.java
new file mode 100644
index 0000000..ac5fd1e
--- /dev/null
+++ b/core/java/android/content/pm/InstallationFile.java
@@ -0,0 +1,118 @@
+/*
+ * 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 android.content.pm;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Defines the properties of a file in an installation session.
+ * TODO(b/136132412): update with new APIs.
+ *
+ * @hide
+ */
+public final class InstallationFile implements Parcelable {
+ public static final int FILE_TYPE_UNKNOWN = -1;
+ public static final int FILE_TYPE_APK = 0;
+ public static final int FILE_TYPE_LIB = 1;
+ public static final int FILE_TYPE_OBB = 2;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"FILE_TYPE_"}, value = {
+ FILE_TYPE_APK,
+ FILE_TYPE_LIB,
+ FILE_TYPE_OBB,
+ })
+ public @interface FileType {
+ }
+
+ private String mFileName;
+ private @FileType int mFileType;
+ private long mFileSize;
+ private byte[] mMetadata;
+
+ public InstallationFile(@NonNull String fileName, long fileSize,
+ @Nullable byte[] metadata) {
+ mFileName = fileName;
+ mFileSize = fileSize;
+ mMetadata = metadata;
+ if (fileName.toLowerCase().endsWith(".apk")) {
+ mFileType = FILE_TYPE_APK;
+ } else if (fileName.toLowerCase().endsWith(".obb")) {
+ mFileType = FILE_TYPE_OBB;
+ } else if (fileName.toLowerCase().endsWith(".so") && fileName.toLowerCase().startsWith(
+ "lib/")) {
+ mFileType = FILE_TYPE_LIB;
+ } else {
+ mFileType = FILE_TYPE_UNKNOWN;
+ }
+ }
+
+ public @FileType int getFileType() {
+ return mFileType;
+ }
+
+ public @NonNull String getName() {
+ return mFileName;
+ }
+
+ public long getSize() {
+ return mFileSize;
+ }
+
+ public @Nullable byte[] getMetadata() {
+ return mMetadata;
+ }
+
+ private InstallationFile(Parcel source) {
+ mFileName = source.readString();
+ mFileType = source.readInt();
+ mFileSize = source.readLong();
+ mMetadata = source.createByteArray();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mFileName);
+ dest.writeInt(mFileType);
+ dest.writeLong(mFileSize);
+ dest.writeByteArray(mMetadata);
+ }
+
+ public static final @NonNull Creator<InstallationFile> CREATOR =
+ new Creator<InstallationFile>() {
+ public InstallationFile createFromParcel(Parcel source) {
+ return new InstallationFile(source);
+ }
+
+ public InstallationFile[] newArray(int size) {
+ return new InstallationFile[size];
+ }
+ };
+
+}
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 4ab6f3c..e9fc8f6 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -50,6 +50,8 @@
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.incremental.IncrementalDataLoaderParams;
+import android.os.incremental.IncrementalDataLoaderParamsParcel;
import android.system.ErrnoException;
import android.system.Os;
import android.util.ArraySet;
@@ -1212,6 +1214,27 @@
}
/**
+ * Configure files for an installation session.
+ *
+ * Currently only for Incremental installation session. Once this method is called,
+ * the files and their paths, as specified in the parameters, will be created and properly
+ * configured in the Incremental File System.
+ *
+ * TODO(b/136132412): update this and InstallationFile class with latest API design.
+ *
+ * @throws IllegalStateException if {@link SessionParams#incrementalParams} is null.
+ *
+ * @hide
+ */
+ public void addFile(@NonNull String name, long size, @NonNull byte[] metadata) {
+ try {
+ mSession.addFile(name, size, metadata);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Release this session object. You can open the session again if it
* hasn't been finalized.
*/
@@ -1398,6 +1421,8 @@
public boolean isStaged;
/** {@hide} */
public long requiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST;
+ /** {@hide} */
+ public IncrementalDataLoaderParams incrementalParams;
/**
* Construct parameters for a new package install session.
@@ -1431,6 +1456,12 @@
isMultiPackage = source.readBoolean();
isStaged = source.readBoolean();
requiredInstalledVersionCode = source.readLong();
+ IncrementalDataLoaderParamsParcel dataLoaderParamsParcel = source.readParcelable(
+ IncrementalDataLoaderParamsParcel.class.getClassLoader());
+ if (dataLoaderParamsParcel != null) {
+ incrementalParams = new IncrementalDataLoaderParams(
+ dataLoaderParamsParcel);
+ }
}
/** {@hide} */
@@ -1454,6 +1485,7 @@
ret.isMultiPackage = isMultiPackage;
ret.isStaged = isStaged;
ret.requiredInstalledVersionCode = requiredInstalledVersionCode;
+ ret.incrementalParams = incrementalParams;
return ret;
}
@@ -1782,6 +1814,16 @@
return (installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0;
}
+ /**
+ * Set Incremental data loader params.
+ *
+ * {@hide}
+ */
+ @RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
+ public void setIncrementalParams(@NonNull IncrementalDataLoaderParams incrementalParams) {
+ this.incrementalParams = incrementalParams;
+ }
+
/** {@hide} */
public void dump(IndentingPrintWriter pw) {
pw.printPair("mode", mode);
@@ -1831,6 +1873,11 @@
dest.writeBoolean(isMultiPackage);
dest.writeBoolean(isStaged);
dest.writeLong(requiredInstalledVersionCode);
+ if (incrementalParams != null) {
+ dest.writeParcelable(incrementalParams.getData(), flags);
+ } else {
+ dest.writeParcelable(null, flags);
+ }
}
public static final Parcelable.Creator<SessionParams>
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index d0ab8f7..50a2f00 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -436,7 +436,7 @@
/**
* @hide
*/
- public void writeToProto(ProtoOutputStream proto, long fieldId, int dumpFlags) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, int dumpFlags) {
long token = proto.start(fieldId);
if (name != null) {
proto.write(PackageItemInfoProto.NAME, name);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index bbfdf91..6e890ba 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -5989,11 +5989,30 @@
*
* @param packageName The name of the package to query
* @throws IllegalArgumentException if the given package name is not installed
+ *
+ * @deprecated use {@link #getInstallSourceInfo(String)} instead
*/
+ @Deprecated
@Nullable
public abstract String getInstallerPackageName(@NonNull String packageName);
/**
+ * Retrieves information about how a package was installed or updated.
+ * <p>
+ * If the calling application does not hold the INSTALL_PACKAGES permission then
+ * the result will always return {@code null} from
+ * {@link InstallSourceInfo#getOriginatingPackageName()}.
+ *
+ * @param packageName The name of the package to query
+ * @throws NameNotFoundException if the given package name is not installed
+ */
+ @NonNull
+ public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName)
+ throws NameNotFoundException {
+ throw new UnsupportedOperationException("getInstallSourceInfo not implemented");
+ }
+
+ /**
* Attempts to clear the user data directory of an application.
* Since this may take a little while, the result will
* be posted back to the given observer. A deletion will fail if the
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 5a45d9f..090629f 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -1115,7 +1115,7 @@
* @param critical If true, reduce amount of data written.
* @hide
*/
- public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId, boolean persisted,
+ public void dumpDebug(ProtoOutputStream protoOutputStream, long fieldId, boolean persisted,
boolean critical) {
final long token = protoOutputStream.start(fieldId);
if (!critical) {
@@ -1138,7 +1138,7 @@
protoOutputStream.write(DENSITY_DPI, densityDpi);
// For persistence, we do not care about window configuration
if (!persisted && windowConfiguration != null) {
- windowConfiguration.writeToProto(protoOutputStream, WINDOW_CONFIGURATION);
+ windowConfiguration.dumpDebug(protoOutputStream, WINDOW_CONFIGURATION);
}
}
protoOutputStream.write(ORIENTATION, orientation);
@@ -1155,8 +1155,8 @@
* @param fieldId Field Id of the Configuration as defined in the parent message
* @hide
*/
- public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
- writeToProto(protoOutputStream, fieldId, false /* persisted */, false /* critical */);
+ public void dumpDebug(ProtoOutputStream protoOutputStream, long fieldId) {
+ dumpDebug(protoOutputStream, fieldId, false /* persisted */, false /* critical */);
}
/**
@@ -1168,8 +1168,8 @@
* @param critical If true, reduce amount of data written.
* @hide
*/
- public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId, boolean critical) {
- writeToProto(protoOutputStream, fieldId, false /* persisted */, critical);
+ public void dumpDebug(ProtoOutputStream protoOutputStream, long fieldId, boolean critical) {
+ dumpDebug(protoOutputStream, fieldId, false /* persisted */, critical);
}
/**
@@ -1338,7 +1338,7 @@
}
final long token = protoOutputStream.start(fieldId);
- writeToProto(protoOutputStream, CONFIGURATION);
+ dumpDebug(protoOutputStream, CONFIGURATION);
protoOutputStream.write(SDK_VERSION, Build.VERSION.RESOURCES_SDK_INT);
protoOutputStream.write(SCREEN_WIDTH_PX, width);
protoOutputStream.write(SCREEN_HEIGHT_PX, height);
diff --git a/core/java/android/content/res/loader/ResourceLoaderManager.java b/core/java/android/content/res/loader/ResourceLoaderManager.java
index ddbfa81..592ec09 100644
--- a/core/java/android/content/res/loader/ResourceLoaderManager.java
+++ b/core/java/android/content/res/loader/ResourceLoaderManager.java
@@ -151,6 +151,7 @@
public void onImplUpdate(ResourcesImpl resourcesImpl) {
synchronized (mLock) {
this.mResourcesImpl = resourcesImpl;
+ this.mResourcesImpl.getAssets().setResourceLoaderManager(this);
updateLoaders();
}
}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/net/MacAddress.aidl
similarity index 80%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/net/MacAddress.aidl
index 007ec94..48a18a7 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/net/MacAddress.aidl
@@ -1,5 +1,6 @@
/**
- * Copyright (c) 2014, The Android Open Source Project
+ *
+ * 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.
@@ -14,6 +15,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.net;
-parcelable WifiActivityEnergyInfo;
+@JavaOnlyStableParcelable parcelable MacAddress;
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 3f56def..c6c73fe 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -63,7 +63,7 @@
/**
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public final int netId;
// Objects used to perform per-network operations such as getSocketFactory
@@ -502,7 +502,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(NetworkProto.NET_ID, netId);
proto.end(token);
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 88877e2..db20dbd 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -1602,7 +1602,7 @@
}
/** @hide */
- public void writeToProto(@NonNull ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
for (int transport : getTransportTypes()) {
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index febc730..c1198aa 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -114,7 +114,7 @@
return builder.append("}").toString();
}
- public void writeToProto(ProtoOutputStream proto, long tag) {
+ public void dumpDebug(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
proto.write(NetworkIdentityProto.TYPE, mType);
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 4270740..adc497a 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -485,13 +485,13 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(NetworkRequestProto.TYPE, typeToProtoEnum(type));
proto.write(NetworkRequestProto.REQUEST_ID, requestId);
proto.write(NetworkRequestProto.LEGACY_TYPE, legacyType);
- networkCapabilities.writeToProto(proto, NetworkRequestProto.NETWORK_CAPABILITIES);
+ networkCapabilities.dumpDebug(proto, NetworkRequestProto.NETWORK_CAPABILITIES);
proto.end(token);
}
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index f61260e..d96d2ee 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -684,7 +684,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long tag) {
+ public void dumpDebug(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS, bucketDuration);
@@ -693,11 +693,11 @@
final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS);
proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS, bucketStart[i]);
- writeToProto(proto, NetworkStatsHistoryBucketProto.RX_BYTES, rxBytes, i);
- writeToProto(proto, NetworkStatsHistoryBucketProto.RX_PACKETS, rxPackets, i);
- writeToProto(proto, NetworkStatsHistoryBucketProto.TX_BYTES, txBytes, i);
- writeToProto(proto, NetworkStatsHistoryBucketProto.TX_PACKETS, txPackets, i);
- writeToProto(proto, NetworkStatsHistoryBucketProto.OPERATIONS, operations, i);
+ dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES, rxBytes, i);
+ dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS, rxPackets, i);
+ dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES, txBytes, i);
+ dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS, txPackets, i);
+ dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS, operations, i);
proto.end(startBucket);
}
@@ -705,7 +705,7 @@
proto.end(start);
}
- private static void writeToProto(ProtoOutputStream proto, long tag, long[] array, int index) {
+ private static void dumpDebug(ProtoOutputStream proto, long tag, long[] array, int index) {
if (array != null) {
proto.write(tag, array[index]);
}
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index 1c6a484..bf4884a 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.TestApi;
@@ -595,8 +596,15 @@
return total;
}
- /** {@hide} */
- public static long getTxPackets(String iface) {
+ /**
+ * Return the number of packets transmitted on the specified interface since
+ * device boot. Statistics are measured at the network layer, so both TCP and
+ * UDP usage are included.
+ *
+ * @param iface The name of the interface.
+ * @return The number of transmitted packets.
+ */
+ public static long getTxPackets(@NonNull String iface) {
try {
return getStatsService().getIfaceStats(iface, TYPE_TX_PACKETS);
} catch (RemoteException e) {
@@ -604,8 +612,15 @@
}
}
- /** {@hide} */
- public static long getRxPackets(String iface) {
+ /**
+ * Return the number of packets received on the specified interface since
+ * device boot. Statistics are measured at the network layer, so both TCP
+ * and UDP usage are included.
+ *
+ * @param iface The name of the interface.
+ * @return The number of received packets.
+ */
+ public static long getRxPackets(@NonNull String iface) {
try {
return getStatsService().getIfaceStats(iface, TYPE_RX_PACKETS);
} catch (RemoteException e) {
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 7e11840..c5b4222 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -1345,7 +1345,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
if (mParcelledData != null) {
diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl
index 29871b6..5ebb9f2 100644
--- a/core/java/android/os/IStatsManager.aidl
+++ b/core/java/android/os/IStatsManager.aidl
@@ -202,6 +202,13 @@
in int[] additiveFields, IPullAtomCallback pullerCallback);
/**
+ * Registers a puller callback function that, when invoked, pulls the data
+ * for the specified atom tag.
+ */
+ oneway void registerNativePullAtomCallback(int atomTag, long coolDownNs, long timeoutNs,
+ in int[] additiveFields, IPullAtomCallback pullerCallback);
+
+ /**
* Unregisters a puller callback function for the given vendor atom.
*
* Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index d468972..df16ffe 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -415,12 +415,12 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long looperToken = proto.start(fieldId);
proto.write(LooperProto.THREAD_NAME, mThread.getName());
proto.write(LooperProto.THREAD_ID, mThread.getId());
if (mQueue != null) {
- mQueue.writeToProto(proto, LooperProto.QUEUE);
+ mQueue.dumpDebug(proto, LooperProto.QUEUE);
}
proto.end(looperToken);
}
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index 6055bef..9d101e5 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -574,7 +574,7 @@
return b.toString();
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long messageToken = proto.start(fieldId);
proto.write(MessageProto.WHEN, when);
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index f98fdc3..b5f4bc6 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -807,11 +807,11 @@
}
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long messageQueueToken = proto.start(fieldId);
synchronized (this) {
for (Message msg = mMessages; msg != null; msg = msg.next) {
- msg.writeToProto(proto, MessageQueueProto.MESSAGES);
+ msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
}
proto.write(MessageQueueProto.IS_POLLING_LOCKED, isPollingLocked());
proto.write(MessageQueueProto.IS_QUITTING, mQuitting);
diff --git a/core/java/android/os/PatternMatcher.java b/core/java/android/os/PatternMatcher.java
index ef03e8c..428405b 100644
--- a/core/java/android/os/PatternMatcher.java
+++ b/core/java/android/os/PatternMatcher.java
@@ -133,7 +133,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(PatternMatcherProto.PATTERN, mPattern);
proto.write(PatternMatcherProto.TYPE, mType);
diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java
index 6f1bf71..b40283f 100644
--- a/core/java/android/os/PersistableBundle.java
+++ b/core/java/android/os/PersistableBundle.java
@@ -324,7 +324,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
if (mParcelledData != null) {
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index f18b4db..725e0fb 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -2315,7 +2315,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
synchronized (mToken) {
final long token = proto.start(fieldId);
proto.write(PowerManagerProto.WakeLock.TAG, mTag);
@@ -2323,7 +2323,7 @@
proto.write(PowerManagerProto.WakeLock.HELD, mHeld);
proto.write(PowerManagerProto.WakeLock.INTERNAL_COUNT, mInternalCount);
if (mWorkSource != null) {
- mWorkSource.writeToProto(proto, PowerManagerProto.WakeLock.WORK_SOURCE);
+ mWorkSource.dumpDebug(proto, PowerManagerProto.WakeLock.WORK_SOURCE);
}
proto.end(token);
}
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index b5635a4..397c2a9 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -1218,7 +1218,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long workSourceToken = proto.start(fieldId);
for (int i = 0; i < mNum; i++) {
final long contentProto = proto.start(WorkSourceProto.WORK_SOURCE_CONTENTS);
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/os/connectivity/WifiActivityEnergyInfo.aidl
similarity index 94%
rename from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
rename to core/java/android/os/connectivity/WifiActivityEnergyInfo.aidl
index 007ec94..ce75c12 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/os/connectivity/WifiActivityEnergyInfo.aidl
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.os.connectivity;
parcelable WifiActivityEnergyInfo;
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java b/core/java/android/os/connectivity/WifiActivityEnergyInfo.java
similarity index 99%
rename from wifi/java/android/net/wifi/WifiActivityEnergyInfo.java
rename to core/java/android/os/connectivity/WifiActivityEnergyInfo.java
index f0f31fa..7db003d 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java
+++ b/core/java/android/os/connectivity/WifiActivityEnergyInfo.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.os.connectivity;
import android.annotation.IntDef;
import android.annotation.NonNull;
diff --git a/core/java/android/os/incremental/IIncrementalServiceProxy.aidl b/core/java/android/os/incremental/IIncrementalServiceProxy.aidl
index 12740ea..ffff52e 100644
--- a/core/java/android/os/incremental/IIncrementalServiceProxy.aidl
+++ b/core/java/android/os/incremental/IIncrementalServiceProxy.aidl
@@ -18,7 +18,7 @@
import android.os.incremental.IncrementalFileSystemControlParcel;
import android.os.incremental.IncrementalDataLoaderParamsParcel;
-import android.service.incremental.IIncrementalDataLoaderStatusListener;
+import android.content.pm.IDataLoaderStatusListener;
/**
* Binder service to receive calls from native Incremental Service and handle Java tasks such as
@@ -29,7 +29,7 @@
boolean prepareDataLoader(int mountId,
in IncrementalFileSystemControlParcel control,
in IncrementalDataLoaderParamsParcel params,
- in IIncrementalDataLoaderStatusListener listener);
+ in IDataLoaderStatusListener listener);
boolean startDataLoader(int mountId);
void showHealthBlockedUI(int mountId);
void destroyDataLoader(int mountId);
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
new file mode 100644
index 0000000..5bd0748
--- /dev/null
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -0,0 +1,280 @@
+/*
+ * 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 android.os.incremental;
+
+/**
+ * Set up files and directories used in an installation session.
+ * Currently only used by Incremental Installation.
+ * For Incremental installation, the expected outcome of this function is:
+ * 0) All the files are in defaultStorage
+ * 1) All APK files are in the same directory, bound to mApkStorage, and bound to the
+ * InstallerSession's stage dir. The files are linked from mApkStorage to defaultStorage.
+ * 2) All lib files are in the sub directories as their names suggest, and in the same parent
+ * directory as the APK files. The files are linked from mApkStorage to defaultStorage.
+ * 3) OBB files are in another directory that is different from APK files and lib files, bound
+ * to mObbStorage. The files are linked from mObbStorage to defaultStorage.
+ *
+ * @throws IllegalStateException the session is not an Incremental installation session.
+ */
+
+import static dalvik.system.VMRuntime.getInstructionSet;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.pm.InstallationFile;
+import android.os.IVold;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.ArraySet;
+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.Random;
+
+/**
+ * This class manages storage instances used during a package installation session.
+ * @hide
+ */
+public final class IncrementalFileStorages {
+ private static final String TAG = "IncrementalFileStorages";
+ private @Nullable IncrementalStorage mDefaultStorage;
+ private @Nullable IncrementalStorage mApkStorage;
+ private @Nullable IncrementalStorage mObbStorage;
+ private @Nullable String mDefaultDir;
+ private @Nullable String mObbDir;
+ private @NonNull IncrementalManager mIncrementalManager;
+ private @Nullable ArraySet<String> mLibDirs;
+ private @NonNull String mPackageName;
+ private @NonNull File mStageDir;
+
+ /**
+ * Set up files and directories used in an installation session.
+ * Currently only used by Incremental Installation.
+ * For Incremental installation, the expected outcome of this function is:
+ * 0) All the files are in defaultStorage
+ * 1) All APK files are in the same directory, bound to mApkStorage, and bound to the
+ * InstallerSession's stage dir. The files are linked from mApkStorage to defaultStorage.
+ * 2) All lib files are in the sub directories as their names suggest, and in the same parent
+ * directory as the APK files. The files are linked from mApkStorage to defaultStorage.
+ * 3) OBB files are in another directory that is different from APK files and lib files, bound
+ * to mObbStorage. The files are linked from mObbStorage to defaultStorage.
+ *
+ * @throws IllegalStateException the session is not an Incremental installation session.
+ */
+ public IncrementalFileStorages(@NonNull String packageName,
+ @NonNull File stageDir,
+ @NonNull IncrementalManager incrementalManager,
+ @NonNull IncrementalDataLoaderParams incrementalDataLoaderParams) {
+ mPackageName = packageName;
+ mStageDir = stageDir;
+ mIncrementalManager = incrementalManager;
+ if (incrementalDataLoaderParams.getPackageName().equals("local")) {
+ final String incrementalPath = incrementalDataLoaderParams.getStaticArgs();
+ mDefaultStorage = mIncrementalManager.openStorage(incrementalPath);
+ mDefaultDir = incrementalPath;
+ return;
+ }
+ mDefaultDir = getTempDir();
+ if (mDefaultDir == null) {
+ return;
+ }
+ mDefaultStorage = mIncrementalManager.createStorage(mDefaultDir,
+ incrementalDataLoaderParams,
+ IncrementalManager.CREATE_MODE_CREATE
+ | IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false);
+ }
+
+ /**
+ * Adds a file into the installation session. Makes sure it will be placed inside
+ * a proper storage instance, based on its file type.
+ */
+ public void addFile(@NonNull InstallationFile file) throws IOException {
+ if (mDefaultStorage == null) {
+ throw new IOException("Cannot add file because default storage does not exist");
+ }
+ if (file.getFileType() == InstallationFile.FILE_TYPE_APK) {
+ addApkFile(file);
+ } else if (file.getFileType() == InstallationFile.FILE_TYPE_OBB) {
+ addObbFile(file);
+ } else if (file.getFileType() == InstallationFile.FILE_TYPE_LIB) {
+ addLibFile(file);
+ } else {
+ throw new IOException("Unknown file type: " + file.getFileType());
+ }
+ }
+
+ private void addApkFile(@NonNull InstallationFile apk) throws IOException {
+ // Create a storage for APK files and lib files
+ final String stageDirPath = mStageDir.getAbsolutePath();
+ if (mApkStorage == null) {
+ mApkStorage = mIncrementalManager.createStorage(stageDirPath, mDefaultStorage,
+ IncrementalManager.CREATE_MODE_CREATE
+ | IncrementalManager.CREATE_MODE_TEMPORARY_BIND);
+ mApkStorage.bind(stageDirPath);
+ }
+
+ if (!new File(mDefaultDir, apk.getName()).exists()) {
+ mDefaultStorage.makeFile(apk.getName(), apk.getSize(),
+ apk.getMetadata());
+ }
+ // Assuming APK files are already named properly, e.g., "base.apk"
+ mDefaultStorage.makeLink(apk.getName(), mApkStorage, apk.getName());
+ }
+
+ private void addLibFile(@NonNull InstallationFile lib) throws IOException {
+ // TODO(b/136132412): remove this after we have incfs support for lib file mapping
+ if (mApkStorage == null) {
+ throw new IOException("Cannot add lib file without adding an apk file first");
+ }
+ if (mLibDirs == null) {
+ mLibDirs = new ArraySet<>();
+ }
+ String current = "";
+ final Path libDirPath = Paths.get(lib.getName()).getParent();
+ final int numDirComponents = libDirPath.getNameCount();
+ for (int i = 0; i < numDirComponents; i++) {
+ String dirName = libDirPath.getName(i).toString();
+ try {
+ dirName = getInstructionSet(dirName);
+ } catch (IllegalArgumentException ignored) {
+ }
+ current += dirName;
+ if (!mLibDirs.contains(current)) {
+ mDefaultStorage.makeDirectory(current);
+ mApkStorage.makeDirectory(current);
+ mLibDirs.add(current);
+ }
+ current += '/';
+ }
+ String libFilePath = current + Paths.get(lib.getName()).getFileName();
+ mDefaultStorage.makeFile(libFilePath, lib.getSize(), lib.getMetadata());
+ mDefaultStorage.makeLink(libFilePath, mApkStorage, libFilePath);
+ }
+
+ private void addObbFile(@NonNull InstallationFile obb) throws IOException {
+ if (mObbStorage == null) {
+ // Create a storage for OBB files
+ mObbDir = getTempDir();
+ if (mObbDir == null) {
+ throw new IOException("Failed to create obb storage directory.");
+ }
+ mObbStorage = mIncrementalManager.createStorage(
+ mObbDir, mDefaultStorage,
+ IncrementalManager.CREATE_MODE_CREATE
+ | IncrementalManager.CREATE_MODE_TEMPORARY_BIND);
+ }
+ mDefaultStorage.makeFile(obb.getName(), obb.getSize(), obb.getMetadata());
+ mDefaultStorage.makeLink(obb.getName(), mObbStorage, obb.getName());
+ }
+
+ private boolean hasObb() {
+ return (mObbStorage != null && mObbDir != null);
+ }
+
+ /**
+ * Starts loading data for default storage.
+ * TODO(b/136132412): update the implementation with latest API design.
+ */
+ public boolean startLoading() {
+ if (mDefaultStorage == null) {
+ return false;
+ }
+ return mDefaultStorage.startLoading();
+ }
+
+ /**
+ * Sets up obb storage directory and create bindings.
+ */
+ public void finishSetUp() {
+ if (!hasObb()) {
+ return;
+ }
+ final String mainObbDir = String.format("/storage/emulated/0/Android/obb/%s", mPackageName);
+ final String packageObbDirRoot =
+ String.format("/mnt/runtime/%s/emulated/0/Android/obb/", mPackageName);
+ final String[] obbDirs = {
+ packageObbDirRoot + "read",
+ packageObbDirRoot + "write",
+ packageObbDirRoot + "full",
+ packageObbDirRoot + "default",
+ String.format("/data/media/0/Android/obb/%s", mPackageName),
+ mainObbDir,
+ };
+ try {
+ Slog.i(TAG, "Creating obb directory '" + mainObbDir + "'");
+ final IVold vold = IVold.Stub.asInterface(ServiceManager.getServiceOrThrow("vold"));
+ vold.mkdirs(mainObbDir);
+ for (String d : obbDirs) {
+ mObbStorage.bindPermanent(d);
+ }
+ } catch (ServiceManager.ServiceNotFoundException ex) {
+ Slog.e(TAG, "vold service is not found.");
+ cleanUp();
+ } catch (IOException | RemoteException ex) {
+ Slog.e(TAG, "Failed to create obb dir at: " + mainObbDir, ex);
+ cleanUp();
+ }
+ }
+
+ /**
+ * Resets the states and unbinds storage instances for an installation session.
+ * TODO(b/136132412): make sure unnecessary binds are removed but useful storages are kept
+ */
+ public void cleanUp() {
+ if (mDefaultStorage != null && mDefaultDir != null) {
+ try {
+ mDefaultStorage.unBind(mDefaultDir);
+ } catch (IOException ignored) {
+ }
+ mDefaultDir = null;
+ mDefaultStorage = null;
+ }
+ if (mApkStorage != null && mStageDir != null) {
+ try {
+ mApkStorage.unBind(mStageDir.getAbsolutePath());
+ } catch (IOException ignored) {
+ }
+ mApkStorage = null;
+ }
+ if (mObbStorage != null && mObbDir != null) {
+ try {
+ mObbStorage.unBind(mObbDir);
+ } catch (IOException ignored) {
+ }
+ mObbDir = null;
+ mObbStorage = null;
+ }
+ }
+
+ private String getTempDir() {
+ final String tmpDirRoot = "/data/tmp";
+ final Random random = new Random();
+ final Path tmpDir =
+ Paths.get(tmpDirRoot, String.valueOf(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/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 6c4ee01..09286fe 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -17,6 +17,7 @@
package android.permission;
import android.Manifest;
+import android.annotation.CallbackExecutor;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -29,6 +30,8 @@
import android.content.pm.IPackageManager;
import android.content.pm.permission.SplitPermissionInfoParcelable;
import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
import android.util.Slog;
import com.android.internal.annotations.Immutable;
@@ -36,6 +39,8 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
/**
* System level service for accessing the permission capabilities of the platform.
@@ -59,6 +64,8 @@
private final IPackageManager mPackageManager;
+ private final IPermissionManager mPermissionManager;
+
private List<SplitPermissionInfo> mSplitPermissionInfos;
/**
@@ -67,9 +74,12 @@
* @param context The current context in which to operate.
* @hide
*/
- public PermissionManager(@NonNull Context context, IPackageManager packageManager) {
+ public PermissionManager(@NonNull Context context, IPackageManager packageManager)
+ throws ServiceManager.ServiceNotFoundException {
mContext = context;
mPackageManager = packageManager;
+ mPermissionManager = IPermissionManager.Stub.asInterface(
+ ServiceManager.getServiceOrThrow("permissionmgr"));
}
/**
@@ -145,6 +155,48 @@
return mSplitPermissionInfos;
}
+ /**
+ * Grant default permissions to currently active LUI app
+ * @param packageName The package name for the LUI app
+ * @param user The user handle
+ * @param callback The callback provided by caller to be notified when grant completes
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS)
+ public void grantDefaultPermissionsToLuiApp(
+ @NonNull String packageName, @NonNull UserHandle user,
+ @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
+ try {
+ mPermissionManager.grantDefaultPermissionsToActiveLuiApp(
+ packageName, user.getIdentifier());
+ executor.execute(() -> callback.accept(true));
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Revoke default permissions to currently active LUI app
+ * @param packageNames The package names for the LUI apps
+ * @param user The user handle
+ * @param callback The callback provided by caller to be notified when grant completes
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS)
+ public void revokeDefaultPermissionsFromLuiApps(
+ @NonNull String[] packageNames, @NonNull UserHandle user,
+ @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
+ try {
+ mPermissionManager.revokeDefaultPermissionsFromLuiApps(
+ packageNames, user.getIdentifier());
+ executor.execute(() -> callback.accept(true));
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
private List<SplitPermissionInfo> splitPermissionInfoListToNonParcelableList(
List<SplitPermissionInfoParcelable> parcelableList) {
final int size = parcelableList.size();
diff --git a/core/java/android/provider/BlockedNumberContract.java b/core/java/android/provider/BlockedNumberContract.java
index 7995f22..1eb7664 100644
--- a/core/java/android/provider/BlockedNumberContract.java
+++ b/core/java/android/provider/BlockedNumberContract.java
@@ -16,7 +16,6 @@
package android.provider;
import android.annotation.IntDef;
-import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.WorkerThread;
import android.content.Context;
@@ -155,12 +154,7 @@
/** The authority for the blocked number provider */
public static final String AUTHORITY = "com.android.blockednumber";
- /**
- * A content:// style uri to the authority for the blocked number provider
- * @hide
- */
- @NonNull
- @SystemApi
+ /** A content:// style uri to the authority for the blocked number provider */
public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
private static final String LOG_TAG = BlockedNumberContract.class.getSimpleName();
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 01f9c73..2c53025 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -20,6 +20,7 @@
import android.annotation.CurrentTimeMillisLong;
import android.annotation.CurrentTimeSecondsLong;
import android.annotation.DurationMillisLong;
+import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -78,6 +79,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collection;
@@ -205,8 +208,10 @@
public static final String PARAM_DELETE_DATA = "deletedata";
/** {@hide} */
+ @Deprecated
public static final String PARAM_INCLUDE_PENDING = "includePending";
/** {@hide} */
+ @Deprecated
public static final String PARAM_INCLUDE_TRASHED = "includeTrashed";
/** {@hide} */
public static final String PARAM_PROGRESS = "progress";
@@ -559,6 +564,101 @@
public static final String UNKNOWN_STRING = "<unknown>";
/**
+ * Specify a {@link Uri} that is "related" to the current operation being
+ * performed.
+ * <p>
+ * This is typically used to allow an operation that may normally be
+ * rejected, such as making a copy of a pre-existing image located under a
+ * {@link MediaColumns#RELATIVE_PATH} where new images are not allowed.
+ * <p>
+ * It's strongly recommended that when making a copy of pre-existing content
+ * that you define the "original document ID" GUID as defined by the <em>XMP
+ * Media Management</em> standard.
+ * <p>
+ * This key can be placed in a {@link Bundle} of extras and passed to
+ * {@link ContentResolver#insert}.
+ */
+ public static final String QUERY_ARG_RELATED_URI = "android:query-arg-related-uri";
+
+ /**
+ * Specify how {@link MediaColumns#IS_PENDING} items should be filtered when
+ * performing a {@link MediaStore} operation.
+ * <p>
+ * This key can be placed in a {@link Bundle} of extras and passed to
+ * {@link ContentResolver#query}, {@link ContentResolver#update}, or
+ * {@link ContentResolver#delete}.
+ * <p>
+ * By default, pending items are filtered away from operations.
+ */
+ @Match
+ public static final String QUERY_ARG_MATCH_PENDING = "android:query-arg-match-pending";
+
+ /**
+ * Specify how {@link MediaColumns#IS_TRASHED} items should be filtered when
+ * performing a {@link MediaStore} operation.
+ * <p>
+ * This key can be placed in a {@link Bundle} of extras and passed to
+ * {@link ContentResolver#query}, {@link ContentResolver#update}, or
+ * {@link ContentResolver#delete}.
+ * <p>
+ * By default, trashed items are filtered away from operations.
+ */
+ @Match
+ public static final String QUERY_ARG_MATCH_TRASHED = "android:query-arg-match-trashed";
+
+ /**
+ * Specify how {@link MediaColumns#IS_FAVORITE} items should be filtered
+ * when performing a {@link MediaStore} operation.
+ * <p>
+ * This key can be placed in a {@link Bundle} of extras and passed to
+ * {@link ContentResolver#query}, {@link ContentResolver#update}, or
+ * {@link ContentResolver#delete}.
+ * <p>
+ * By default, favorite items are <em>not</em> filtered away from
+ * operations.
+ */
+ @Match
+ public static final String QUERY_ARG_MATCH_FAVORITE = "android:query-arg-match-favorite";
+
+ /** @hide */
+ @IntDef(flag = true, prefix = { "MATCH_" }, value = {
+ MATCH_DEFAULT,
+ MATCH_INCLUDE,
+ MATCH_EXCLUDE,
+ MATCH_ONLY,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Match {}
+
+ /**
+ * Value indicating that the default matching behavior should be used, as
+ * defined by the key documentation.
+ */
+ public static final int MATCH_DEFAULT = 0;
+
+ /**
+ * Value indicating that operations should include items matching the
+ * criteria defined by this key.
+ * <p>
+ * Note that items <em>not</em> matching the criteria <em>may</em> also be
+ * included depending on the default behavior documented by the key. If you
+ * want to operate exclusively on matching items, use {@link #MATCH_ONLY}.
+ */
+ public static final int MATCH_INCLUDE = 1;
+
+ /**
+ * Value indicating that operations should exclude items matching the
+ * criteria defined by this key.
+ */
+ public static final int MATCH_EXCLUDE = 2;
+
+ /**
+ * Value indicating that operations should only operate on items explicitly
+ * matching the criteria defined by this key.
+ */
+ public static final int MATCH_ONLY = 3;
+
+ /**
* Update the given {@link Uri} to also include any pending media items from
* calls such as
* {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
@@ -566,12 +666,16 @@
*
* @see MediaColumns#IS_PENDING
* @see MediaStore#getIncludePending(Uri)
+ * @deprecated consider migrating to {@link #QUERY_ARG_MATCH_PENDING} which
+ * is more expressive.
*/
+ @Deprecated
public static @NonNull Uri setIncludePending(@NonNull Uri uri) {
return setIncludePending(uri.buildUpon()).build();
}
/** @hide */
+ @Deprecated
public static @NonNull Uri.Builder setIncludePending(@NonNull Uri.Builder uriBuilder) {
return uriBuilder.appendQueryParameter(PARAM_INCLUDE_PENDING, "1");
}
@@ -582,7 +686,11 @@
*
* @see MediaColumns#IS_PENDING
* @see MediaStore#setIncludePending(Uri)
+ * @deprecated consider migrating to {@link #QUERY_ARG_MATCH_PENDING} which
+ * is more expressive.
+ * @removed
*/
+ @Deprecated
public static boolean getIncludePending(@NonNull Uri uri) {
return parseBoolean(uri.getQueryParameter(MediaStore.PARAM_INCLUDE_PENDING));
}
@@ -597,7 +705,11 @@
* @see MediaStore#setIncludeTrashed(Uri)
* @see MediaStore#trash(Context, Uri)
* @see MediaStore#untrash(Context, Uri)
+ * @deprecated consider migrating to {@link #QUERY_ARG_MATCH_TRASHED} which
+ * is more expressive.
+ * @removed
*/
+ @Deprecated
public static @NonNull Uri setIncludeTrashed(@NonNull Uri uri) {
return uri.buildUpon().appendQueryParameter(PARAM_INCLUDE_TRASHED, "1").build();
}
@@ -1000,7 +1112,7 @@
* the field to {@code 0}, or until they expire as defined by
* {@link #DATE_EXPIRES}.
*
- * @see MediaStore#setIncludePending(Uri)
+ * @see MediaStore#QUERY_ARG_MATCH_PENDING
*/
@Column(Cursor.FIELD_TYPE_INTEGER)
public static final String IS_PENDING = "is_pending";
@@ -1011,8 +1123,7 @@
* Trashed items are retained until they expire as defined by
* {@link #DATE_EXPIRES}.
*
- * @see MediaColumns#IS_TRASHED
- * @see MediaStore#setIncludeTrashed(Uri)
+ * @see MediaStore#QUERY_ARG_MATCH_TRASHED
* @see MediaStore#trash(Context, Uri)
* @see MediaStore#untrash(Context, Uri)
*/
@@ -1186,6 +1297,8 @@
/**
* Flag indicating if the media item has been marked as being a
* "favorite" by the user.
+ *
+ * @see MediaStore#QUERY_ARG_MATCH_FAVORITE
*/
@Column(Cursor.FIELD_TYPE_INTEGER)
public static final String IS_FAVORITE = "is_favorite";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index fa8896e..ad8d553 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8782,6 +8782,22 @@
public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu";
/**
+ * The package name for the custom bugreport handler app. This app must be whitelisted.
+ * This is currently used only by Power Menu short press.
+ *
+ * @hide
+ */
+ public static final String CUSTOM_BUGREPORT_HANDLER_APP = "custom_bugreport_handler_app";
+
+ /**
+ * The user id for the custom bugreport handler app. This is currently used only by Power
+ * Menu short press.
+ *
+ * @hide
+ */
+ public static final String CUSTOM_BUGREPORT_HANDLER_USER = "custom_bugreport_handler_user";
+
+ /**
* Whether ADB is enabled.
*/
public static final String ADB_ENABLED = "adb_enabled";
@@ -8918,14 +8934,33 @@
* List of ISO country codes in which eUICC UI is shown. Country codes should be separated
* by comma.
*
- * <p>Used to hide eUICC UI from users who are currently in countries no carriers support
- * eUICC.
+ * Note: if {@link #EUICC_SUPPORTED_COUNTRIES} is empty, then {@link
+ * #EUICC_UNSUPPORTED_COUNTRIES} is used.
+ *
+ * <p>Used to hide eUICC UI from users who are currently in countries where no carriers
+ * support eUICC.
+ *
* @hide
*/
- //TODO(b/77914569) Changes this to System Api.
+ @SystemApi
public static final String EUICC_SUPPORTED_COUNTRIES = "euicc_supported_countries";
/**
+ * List of ISO country codes in which eUICC UI is not shown. Country codes should be
+ * separated by comma.
+ *
+ * Note: if {@link #EUICC_SUPPORTED_COUNTRIES} is empty, then {@link
+ * #EUICC_UNSUPPORTED_COUNTRIES} is used.
+ *
+ * <p>Used to hide eUICC UI from users who are currently in countries where no carriers
+ * support eUICC.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String EUICC_UNSUPPORTED_COUNTRIES = "euicc_unsupported_countries";
+
+ /**
* Whether any activity can be resized. When this is true, any
* activity, regardless of manifest values, can be resized for multi-window.
* (0 = false, 1 = true)
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 9e454e6..22f90f6 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -44,7 +44,6 @@
import android.text.TextUtils;
import android.util.Patterns;
-import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.SmsApplication;
import java.lang.annotation.Retention;
@@ -1379,7 +1378,7 @@
}
String format = intent.getStringExtra("format");
- int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+ int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
SubscriptionManager.getDefaultSmsSubscriptionId());
Rlog.v(TAG, " getMessagesFromIntent sub_id : " + subId);
@@ -4505,7 +4504,7 @@
/**
* The current registered voice network operator name in long alphanumeric format.
* <p>
- * This is the same as {@link ServiceState#getVoiceOperatorAlphaLong()}.
+ * This is the same as {@link ServiceState#getOperatorAlphaLong()}.
* @hide
*/
public static final String VOICE_OPERATOR_ALPHA_LONG = "voice_operator_alpha_long";
@@ -4516,12 +4515,11 @@
* In GSM/UMTS, short format can be up to 8 characters long. The current registered voice
* network operator name in long alphanumeric format.
* <p>
- * This is the same as {@link ServiceState#getVoiceOperatorAlphaShort()}.
+ * This is the same as {@link ServiceState#getOperatorAlphaShort()}.
* @hide
*/
public static final String VOICE_OPERATOR_ALPHA_SHORT = "voice_operator_alpha_short";
-
/**
* The current registered operator numeric id.
* <p>
@@ -4535,7 +4533,7 @@
/**
* The current registered data network operator name in long alphanumeric format.
* <p>
- * This is the same as {@link ServiceState#getDataOperatorAlphaLong()}.
+ * This is the same as {@link ServiceState#getOperatorAlphaLong()}.
* @hide
*/
public static final String DATA_OPERATOR_ALPHA_LONG = "data_operator_alpha_long";
@@ -4543,7 +4541,7 @@
/**
* The current registered data network operator name in short alphanumeric format.
* <p>
- * This is the same as {@link ServiceState#getDataOperatorAlphaShort()}.
+ * This is the same as {@link ServiceState#getOperatorAlphaShort()}.
* @hide
*/
public static final String DATA_OPERATOR_ALPHA_SHORT = "data_operator_alpha_short";
@@ -4551,7 +4549,7 @@
/**
* The current registered data network operator numeric id.
* <p>
- * This is the same as {@link ServiceState#getDataOperatorNumeric()}.
+ * This is the same as {@link ServiceState#getOperatorNumeric()}.
* @hide
*/
public static final String DATA_OPERATOR_NUMERIC = "data_operator_numeric";
diff --git a/core/java/android/service/autofill/augmented/FillWindow.java b/core/java/android/service/autofill/augmented/FillWindow.java
index 6a29d48..5d00370 100644
--- a/core/java/android/service/autofill/augmented/FillWindow.java
+++ b/core/java/android/service/autofill/augmented/FillWindow.java
@@ -242,6 +242,7 @@
synchronized (mLock) {
if (mDestroyed) return;
if (mUpdateCalled) {
+ mFillView.setOnClickListener(null);
hide();
mProxy.report(AutofillProxy.REPORT_EVENT_UI_DESTROYED);
}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/service/controls/BooleanAction.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/service/controls/BooleanAction.aidl
index 007ec94..730ad36 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/service/controls/BooleanAction.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.service.controls;
-parcelable WifiActivityEnergyInfo;
+parcelable BooleanAction;
\ No newline at end of file
diff --git a/core/java/android/service/controls/BooleanAction.java b/core/java/android/service/controls/BooleanAction.java
new file mode 100644
index 0000000..8508c63
--- /dev/null
+++ b/core/java/android/service/controls/BooleanAction.java
@@ -0,0 +1,93 @@
+/*
+ * 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 android.service.controls;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+
+/**
+ * Action sent by a {@link ToggleTemplate}
+ * @hide
+ */
+public final class BooleanAction extends ControlAction {
+
+ private final boolean mNewState;
+
+ /**
+ * @param templateId the identifier of the {@link ToggleTemplate} that produced this action.
+ * @param newState new value for the state displayed by the {@link ToggleTemplate}.
+ */
+ public BooleanAction(@NonNull String templateId, boolean newState) {
+ this(templateId, newState, null);
+ }
+
+ /**
+ * @param templateId the identifier of the {@link ToggleTemplate} that originated this action.
+ * @param newValue new value for the state displayed by the {@link ToggleTemplate}.
+ * @param challengeValue a value sent by the user along with the action to authenticate. {@code}
+ * null is sent when no authentication is needed or has not been
+ * requested.
+ */
+ public BooleanAction(@NonNull String templateId, boolean newValue,
+ @Nullable String challengeValue) {
+ super(templateId, challengeValue);
+ mNewState = newValue;
+ }
+
+ BooleanAction(Parcel in) {
+ super(in);
+ mNewState = in.readByte() == 1;
+ }
+
+ /**
+ * The new state set for the button in the corresponding {@link ToggleTemplate}.
+ *
+ * @return {@code true} if the button was toggled from an {@code off} state to an {@code on}
+ * state.
+ */
+ public boolean getNewState() {
+ return mNewState;
+ }
+
+ /**
+ * @return {@link ControlAction#TYPE_BOOLEAN}
+ */
+ @Override
+ public int getActionType() {
+ return ControlAction.TYPE_BOOLEAN;
+ }
+
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeByte(mNewState ? (byte) 1 : (byte) 0);
+ }
+
+ public static final @NonNull Creator<BooleanAction> CREATOR = new Creator<BooleanAction>() {
+ @Override
+ public BooleanAction createFromParcel(Parcel source) {
+ return new BooleanAction(source);
+ }
+
+ @Override
+ public BooleanAction[] newArray(int size) {
+ return new BooleanAction[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/service/controls/Control.aidl
similarity index 81%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/service/controls/Control.aidl
index 007ec94..f4964f2 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/service/controls/Control.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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.
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.service.controls;
-parcelable WifiActivityEnergyInfo;
+parcelable Control;
\ No newline at end of file
diff --git a/core/java/android/service/controls/Control.java b/core/java/android/service/controls/Control.java
new file mode 100644
index 0000000..a69408c
--- /dev/null
+++ b/core/java/android/service/controls/Control.java
@@ -0,0 +1,284 @@
+/*
+ * 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 android.service.controls;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.drawable.Icon;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Represents a physical object that can be represented by a {@link ControlTemplate} and whose
+ * properties may be modified through a {@link ControlAction}.
+ *
+ * The information is provided by a {@link ControlProviderService} and represents static
+ * information (not current status) about the device.
+ * <p>
+ * Each control needs a unique (per provider) identifier that is persistent across reboots of the
+ * system.
+ * <p>
+ * Each {@link Control} will have a name and an icon. The name is usually set up by the user in the
+ * {@link ControlProvider} while the icon is usually decided by the {@link ControlProvider} based
+ * on the type of device.
+ * <p>
+ * The {@link ControlTemplate.TemplateType} provided will be used as a hint when displaying this in
+ * non-interactive situations (for example when there's no state to display). This template is not
+ * the one that will be shown with the current state and provide interactions. That template is set
+ * using {@link ControlState}.
+ * <p>
+ * An {@link Intent} linking to the provider Activity that expands this {@link Control} should be
+ * provided.
+ * @hide
+ */
+public class Control implements Parcelable {
+
+ private final @NonNull String mControlId;
+ private final @NonNull Icon mIcon;
+ private final @NonNull CharSequence mTitle;
+ private final @Nullable ColorStateList mTintColor;
+ private final @NonNull Intent mAppIntent;
+ private final @ControlTemplate.TemplateType int mPrimaryType;
+
+ /**
+ * @param controlId the unique persistent identifier for this object.
+ * @param icon an icon to display identifying the control.
+ * @param title the user facing name of this control (e.g. "Bedroom thermostat").
+ * @param tintColor the color to tint parts of the element UI. If {@code null} is passed, the
+ * system accent color will be used.
+ * @param appIntent an intent linking to a page to interact with the corresponding device.
+ * @param primaryType the primary template for this type.
+ */
+ public Control(@NonNull String controlId,
+ @NonNull Icon icon,
+ @NonNull CharSequence title,
+ @Nullable ColorStateList tintColor,
+ @NonNull Intent appIntent,
+ int primaryType) {
+ Preconditions.checkNotNull(controlId);
+ Preconditions.checkNotNull(icon);
+ Preconditions.checkNotNull(title);
+ Preconditions.checkNotNull(appIntent);
+ mControlId = controlId;
+ mIcon = icon;
+ mTitle = title;
+ mTintColor = tintColor;
+ mAppIntent = appIntent;
+ mPrimaryType = primaryType;
+ }
+
+ public Control(Parcel in) {
+ mControlId = in.readString();
+ mIcon = Icon.CREATOR.createFromParcel(in);
+ mTitle = in.readCharSequence();
+ if (in.readByte() == 1) {
+ mTintColor = ColorStateList.CREATOR.createFromParcel(in);
+ } else {
+ mTintColor = null;
+ }
+ mAppIntent = Intent.CREATOR.createFromParcel(in);
+ mPrimaryType = in.readInt();
+ }
+
+ @NonNull
+ public String getControlId() {
+ return mControlId;
+ }
+
+ @NonNull
+ public Icon getIcon() {
+ return mIcon;
+ }
+
+ @NonNull
+ public CharSequence getTitle() {
+ return mTitle;
+ }
+
+ @Nullable
+ public ColorStateList getTint() {
+ return mTintColor;
+ }
+
+ @NonNull
+ public Intent getAppIntent() {
+ return mAppIntent;
+ }
+
+ @ControlTemplate.TemplateType
+ public int getPrimaryType() {
+ return mPrimaryType;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mControlId);
+ mIcon.writeToParcel(dest, flags);
+ dest.writeCharSequence(mTitle);
+ if (mTintColor != null) {
+ dest.writeByte((byte) 1);
+ mTintColor.writeToParcel(dest, flags);
+ } else {
+ dest.writeByte((byte) 0);
+ }
+ mAppIntent.writeToParcel(dest, flags);
+ dest.writeInt(mPrimaryType);
+ }
+
+ public static final Creator<Control> CREATOR = new Creator<Control>() {
+ @Override
+ public Control createFromParcel(Parcel source) {
+ return new Control(source);
+ }
+
+ @Override
+ public Control[] newArray(int size) {
+ return new Control[size];
+ }
+ };
+
+ /**
+ * Builder class for {@link Control}.
+ *
+ * This class facilitates the creation of {@link Control}. It provides the following
+ * defaults for non-optional parameters:
+ * <ul>
+ * <li> Title: {@code ""}
+ * <li> Primary template: {@link ControlTemplate#TYPE_NONE}
+ * </ul>
+ */
+ public static class Builder {
+ private String mControlId;
+ private Icon mIcon;
+ private CharSequence mTitle = "";
+ private ColorStateList mTintColor;
+ private @Nullable Intent mAppIntent;
+ private @ControlTemplate.TemplateType int mPrimaryType = ControlTemplate.TYPE_NONE;
+
+ /**
+ * @param controlId the identifier for the {@link Control}.
+ * @param icon the icon for the {@link Control}.
+ * @param appIntent the intent linking to the device Activity.
+ */
+ public Builder(@NonNull String controlId,
+ @NonNull Icon icon,
+ @NonNull Intent appIntent) {
+ Preconditions.checkNotNull(controlId);
+ Preconditions.checkNotNull(icon);
+ Preconditions.checkNotNull(appIntent);
+ mControlId = controlId;
+ mIcon = icon;
+ mAppIntent = appIntent;
+ }
+
+ /**
+ * Creates a {@link Builder} using an existing {@link Control} as a base.
+ * @param control base for the builder.
+ */
+ public Builder(@NonNull Control control) {
+ Preconditions.checkNotNull(control);
+ mControlId = control.mControlId;
+ mIcon = control.mIcon;
+ mTitle = control.mTitle;
+ mTintColor = control.mTintColor;
+ mAppIntent = control.mAppIntent;
+ mPrimaryType = control.mPrimaryType;
+ }
+
+ /**
+ * @param controlId the identifier for the {@link Control}.
+ * @return {@code this}
+ */
+ public Builder setControlId(@NonNull String controlId) {
+ Preconditions.checkNotNull(controlId);
+ mControlId = controlId;
+ return this;
+ }
+
+ /**
+ * @param icon the icon for the {@link Control}
+ * @return {@code this}
+ */
+ @NonNull
+ public Builder setIcon(@NonNull Icon icon) {
+ Preconditions.checkNotNull(icon);
+ mIcon = icon;
+ return this;
+ }
+
+ /**
+ * @param title the user facing name of the {@link Control}
+ * @return {@code this}
+ */
+ @NonNull
+ public Builder setTitle(@NonNull CharSequence title) {
+ Preconditions.checkNotNull(title);
+ mTitle = title;
+ return this;
+ }
+
+ /**
+ * @param tint colors for tinting parts of the {@link Control} UI. Passing {@code null} will
+ * default to using the current color accent.
+ * @return {@code this}
+ */
+ @NonNull
+ public Builder setTint(@Nullable ColorStateList tint) {
+ mTintColor = tint;
+ return this;
+ }
+
+ /**
+ * @param appIntent an {@link Intent} linking to an Activity for the {@link Control}
+ * @return {@code this}
+ */
+ @NonNull
+ public Builder setAppIntent(@NonNull Intent appIntent) {
+ Preconditions.checkNotNull(appIntent);
+ mAppIntent = appIntent;
+ return this;
+ }
+
+ /**
+ * @param type type to use as default in the {@link Control}
+ * @return {@code this}
+ */
+ @NonNull
+ public Builder setPrimaryType(@ControlTemplate.TemplateType int type) {
+ mPrimaryType = type;
+ return this;
+ }
+
+ /**
+ * Build a {@link Control}
+ * @return a valid {@link Control}
+ */
+ @NonNull
+ public Control build() {
+ return new Control(mControlId, mIcon, mTitle, mTintColor, mAppIntent, mPrimaryType);
+ }
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/service/controls/ControlAction.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/service/controls/ControlAction.aidl
index 007ec94..e1a5276 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/service/controls/ControlAction.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.service.controls;
-parcelable WifiActivityEnergyInfo;
+parcelable ControlAction;
\ No newline at end of file
diff --git a/core/java/android/service/controls/ControlAction.java b/core/java/android/service/controls/ControlAction.java
new file mode 100644
index 0000000..8b75955
--- /dev/null
+++ b/core/java/android/service/controls/ControlAction.java
@@ -0,0 +1,189 @@
+/*
+ * 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 android.service.controls;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An abstract action that is executed from a {@link ControlTemplate}.
+ *
+ * The action may have a value to authenticate the input, when the provider has requested it to
+ * complete the action.
+ * @hide
+ */
+public abstract class ControlAction implements Parcelable {
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ TYPE_BOOLEAN,
+ TYPE_FLOAT
+ })
+ public @interface ActionType {};
+
+ /**
+ * The identifier of {@link BooleanAction}.
+ */
+ public static final @ActionType int TYPE_BOOLEAN = 0;
+
+ /**
+ * The identifier of {@link FloatAction}.
+ */
+ public static final @ActionType int TYPE_FLOAT = 1;
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ RESPONSE_OK,
+ RESPONSE_FAIL,
+ RESPONSE_CHALLENGE_ACK,
+ RESPONSE_CHALLENGE_PIN,
+ RESPONSE_CHALLENGE_PASSPHRASE
+ })
+ public @interface ResponseResult {};
+
+ /**
+ * Response code for {@link IControlsProviderCallback#onControlActionResponse} indicating that
+ * the action has been performed. The action may still fail later and the state may not change.
+ */
+ public static final @ResponseResult int RESPONSE_OK = 0;
+ /**
+ * Response code for {@link IControlsProviderCallback#onControlActionResponse} indicating that
+ * the action has failed.
+ */
+ public static final @ResponseResult int RESPONSE_FAIL = 1;
+ /**
+ * Response code for {@link IControlsProviderCallback#onControlActionResponse} indicating that
+ * in order for the action to be performed, acknowledgment from the user is required.
+ */
+ public static final @ResponseResult int RESPONSE_CHALLENGE_ACK = 2;
+ /**
+ * Response code for {@link IControlsProviderCallback#onControlActionResponse} indicating that
+ * in order for the action to be performed, a PIN is required.
+ */
+ public static final @ResponseResult int RESPONSE_CHALLENGE_PIN = 3;
+ /**
+ * Response code for {@link IControlsProviderCallback#onControlActionResponse} indicating that
+ * in order for the action to be performed, an alphanumeric passphrase is required.
+ */
+ public static final @ResponseResult int RESPONSE_CHALLENGE_PASSPHRASE = 4;
+
+ /**
+ * The {@link ActionType} associated with this class.
+ */
+ public abstract @ActionType int getActionType();
+
+ private final @NonNull String mTemplateId;
+ private final @Nullable String mChallengeValue;
+
+ private ControlAction() {
+ mTemplateId = "";
+ mChallengeValue = null;
+ }
+
+ /**
+ * @hide
+ */
+ ControlAction(@NonNull String templateId, @Nullable String challengeValue) {
+ Preconditions.checkNotNull(templateId);
+ mTemplateId = templateId;
+ mChallengeValue = challengeValue;
+ }
+
+ /**
+ * @hide
+ */
+ ControlAction(Parcel in) {
+ mTemplateId = in.readString();
+ if (in.readByte() == 1) {
+ mChallengeValue = in.readString();
+ } else {
+ mChallengeValue = null;
+ }
+ }
+
+ /**
+ * The identifier of the {@link ControlTemplate} that originated this action
+ */
+ @NonNull
+ public String getTemplateId() {
+ return mTemplateId;
+ }
+
+ /**
+ * The challenge value used to authenticate certain actions, if available.
+ */
+ @Nullable
+ public String getChallengeValue() {
+ return mChallengeValue;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(getActionType());
+ dest.writeString(mTemplateId);
+ if (mChallengeValue != null) {
+ dest.writeByte((byte) 1);
+ dest.writeString(mChallengeValue);
+ } else {
+ dest.writeByte((byte) 0);
+ }
+ }
+
+ public static final @NonNull Creator<ControlAction> CREATOR = new Creator<ControlAction>() {
+ @Override
+ public ControlAction createFromParcel(Parcel source) {
+ int type = source.readInt();
+ return createActionFromType(type, source);
+ }
+
+ @Override
+ public ControlAction[] newArray(int size) {
+ return new ControlAction[size];
+ }
+ };
+
+ private static ControlAction createActionFromType(@ActionType int type, Parcel source) {
+ switch(type) {
+ case TYPE_BOOLEAN:
+ return BooleanAction.CREATOR.createFromParcel(source);
+ case TYPE_FLOAT:
+ return FloatAction.CREATOR.createFromParcel(source);
+ default:
+ return null;
+ }
+ }
+
+}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/service/controls/ControlButton.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/service/controls/ControlButton.aidl
index 007ec94..6a7262d 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/service/controls/ControlButton.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.service.controls;
-parcelable WifiActivityEnergyInfo;
+parcelable ControlButton;
\ No newline at end of file
diff --git a/core/java/android/service/controls/ControlButton.java b/core/java/android/service/controls/ControlButton.java
new file mode 100644
index 0000000..fed3115
--- /dev/null
+++ b/core/java/android/service/controls/ControlButton.java
@@ -0,0 +1,103 @@
+/*
+ * 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 android.service.controls;
+
+import android.annotation.NonNull;
+import android.graphics.drawable.Icon;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Button element for {@link ControlTemplate}.
+ * @hide
+ */
+public class ControlButton implements Parcelable {
+
+ private final boolean mActive;
+ private final @NonNull Icon mIcon;
+ private final @NonNull CharSequence mContentDescription;
+
+ /**
+ * @param active true if the button should be rendered as active.
+ * @param icon icon to display in the button.
+ * @param contentDescription content description for the button.
+ */
+ public ControlButton(boolean active, @NonNull Icon icon,
+ @NonNull CharSequence contentDescription) {
+ Preconditions.checkNotNull(icon);
+ Preconditions.checkNotNull(contentDescription);
+ mActive = active;
+ mIcon = icon;
+ mContentDescription = contentDescription;
+ }
+
+ /**
+ * Whether the button should be rendered in its active state.
+ */
+ public boolean isActive() {
+ return mActive;
+ }
+
+ /**
+ * The icon for this button.
+ */
+ @NonNull
+ public Icon getIcon() {
+ return mIcon;
+ }
+
+ /**
+ * The content description for this button.
+ */
+ @NonNull
+ public CharSequence getContentDescription() {
+ return mContentDescription;
+ }
+
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeByte(mActive ? (byte) 1 : (byte) 0);
+ mIcon.writeToParcel(dest, flags);
+ dest.writeCharSequence(mContentDescription);
+ }
+
+ ControlButton(Parcel in) {
+ mActive = in.readByte() != 0;
+ mIcon = Icon.CREATOR.createFromParcel(in);
+ mContentDescription = in.readCharSequence();
+ }
+
+ public static final Creator<ControlButton> CREATOR = new Creator<ControlButton>() {
+ @Override
+ public ControlButton createFromParcel(Parcel source) {
+ return new ControlButton(source);
+ }
+
+ @Override
+ public ControlButton[] newArray(int size) {
+ return new ControlButton[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/service/controls/ControlState.aidl
similarity index 81%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/service/controls/ControlState.aidl
index 007ec94..520d85b 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/service/controls/ControlState.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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.
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.service.controls;
-parcelable WifiActivityEnergyInfo;
+parcelable ControlState;
\ No newline at end of file
diff --git a/core/java/android/service/controls/ControlState.java b/core/java/android/service/controls/ControlState.java
new file mode 100644
index 0000000..804aef7
--- /dev/null
+++ b/core/java/android/service/controls/ControlState.java
@@ -0,0 +1,318 @@
+/*
+ * 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 android.service.controls;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.ColorStateList;
+import android.graphics.drawable.Icon;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Current state for a {@link Control}.
+ *
+ * Collects information to render the current state of a {@link Control} as well as possible action
+ * that can be performed on it. Some of the information may temporarily override the defaults
+ * provided by the corresponding {@link Control}, while this state is being displayed.
+ *
+ * Additionally, this can be used to modify information related to the corresponding
+ * {@link Control}.
+ * @hide
+ */
+public final class ControlState implements Parcelable {
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ STATUS_OK,
+ STATUS_NOT_FOUND,
+ STATUS_ERROR,
+ STATUS_DISABLED,
+ })
+ public @interface Status {};
+
+ /**
+ * The device corresponding to the {@link Control} is responding correctly.
+ */
+ public static final int STATUS_OK = 0;
+
+ /**
+ * The device corresponding to the {@link Control} cannot be found or was removed.
+ */
+ public static final int STATUS_NOT_FOUND = 1;
+
+ /**
+ * The device corresponding to the {@link Control} is in an error state.
+ */
+ public static final int STATUS_ERROR = 2;
+
+ /**
+ * The {@link Control} is currently disabled.
+ */
+ public static final int STATUS_DISABLED = 3;
+
+ private final @NonNull Control mControl;
+ private final @Status int mStatus;
+ private final @NonNull ControlTemplate mControlTemplate;
+ private final @NonNull CharSequence mStatusText;
+ private final @Nullable Icon mOverrideIcon;
+ private final @Nullable ColorStateList mOverrideTint;
+
+ /**
+ * @param control the {@link Control} this state should be applied to. Can be used to
+ * update information about the {@link Control}
+ * @param status the current status of the {@link Control}.
+ * @param controlTemplate the template to be used to render the {@link Control}.
+ * @param statusText the text describing the current status.
+ * @param overrideIcon the icon to temporarily override the one provided in
+ * {@link Control#getIcon()}. Pass {@code null} to use the icon in
+ * {@link Control#getIcon()}.
+ * @param overrideTint the colors to temporarily override those provided in
+ * {@link Control#getTint()}. Pass {@code null} to use the colors in
+ * {@link Control#getTint()}.
+ */
+ public ControlState(@NonNull Control control,
+ int status,
+ @NonNull ControlTemplate controlTemplate,
+ @NonNull CharSequence statusText,
+ @Nullable Icon overrideIcon,
+ @Nullable ColorStateList overrideTint) {
+ Preconditions.checkNotNull(control);
+ Preconditions.checkNotNull(controlTemplate);
+ Preconditions.checkNotNull(statusText);
+
+ mControl = control;
+ mStatus = status;
+ mControlTemplate = controlTemplate;
+ mOverrideIcon = overrideIcon;
+ mStatusText = statusText;
+ mOverrideTint = overrideTint;
+ }
+
+ ControlState(Parcel in) {
+ mControl = Control.CREATOR.createFromParcel(in);
+ mStatus = in.readInt();
+ mControlTemplate = ControlTemplate.CREATOR.createFromParcel(in);
+ mStatusText = in.readCharSequence();
+ if (in.readByte() == 1) {
+ mOverrideIcon = Icon.CREATOR.createFromParcel(in);
+ } else {
+ mOverrideIcon = null;
+ }
+ if (in.readByte() == 1) {
+ mOverrideTint = ColorStateList.CREATOR.createFromParcel(in);
+ } else {
+ mOverrideTint = null;
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Status
+ public int getStatus() {
+ return mStatus;
+ }
+
+ @NonNull
+ public ControlTemplate getControlTemplate() {
+ return mControlTemplate;
+ }
+
+ @Nullable
+ public Icon getOverrideIcon() {
+ return mOverrideIcon;
+ }
+
+ @NonNull
+ public CharSequence getStatusText() {
+ return mStatusText;
+ }
+
+ @Nullable
+ public ColorStateList getOverrideTint() {
+ return mOverrideTint;
+ }
+
+ @NonNull
+ public Control getControl() {
+ return mControl;
+ }
+
+ @NonNull
+ public String getControlId() {
+ return mControl.getControlId();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ mControl.writeToParcel(dest, flags);
+ dest.writeInt(mStatus);
+ mControlTemplate.writeToParcel(dest, flags);
+ dest.writeCharSequence(mStatusText);
+ if (mOverrideIcon != null) {
+ dest.writeByte((byte) 1);
+ mOverrideIcon.writeToParcel(dest, flags);
+ } else {
+ dest.writeByte((byte) 0);
+ }
+ if (mOverrideTint != null) {
+ dest.writeByte((byte) 1);
+ mOverrideTint.writeToParcel(dest, flags);
+ } else {
+ dest.writeByte((byte) 0);
+ }
+ }
+
+ public static final Creator<ControlState> CREATOR = new Creator<ControlState>() {
+ @Override
+ public ControlState createFromParcel(Parcel source) {
+ return new ControlState(source);
+ }
+
+ @Override
+ public ControlState[] newArray(int size) {
+ return new ControlState[size];
+ }
+ };
+
+ /**
+ * Builder class for {@link ControlState}.
+ *
+ * This class facilitates the creation of {@link ControlState}. It provides the following
+ * defaults for non-optional parameters:
+ * <ul>
+ * <li> Status: {@link ControlState#STATUS_OK}
+ * <li> Control template: {@link ControlTemplate#NO_TEMPLATE}
+ * <li> Status text: {@code ""}
+ * </ul>
+ */
+ public static class Builder {
+ private @NonNull Control mControl;
+ private @Status int mStatus = STATUS_OK;
+ private @NonNull ControlTemplate mControlTemplate = ControlTemplate.NO_TEMPLATE;
+ private @NonNull CharSequence mStatusText = "";
+ private @Nullable Icon mOverrideIcon;
+ private @Nullable ColorStateList mOverrideTint;
+
+ /**
+ * @param control the {@link Control} that the resulting {@link ControlState} refers to.
+ */
+ public Builder(@NonNull Control control) {
+ Preconditions.checkNotNull(control);
+ mControl = control;
+ }
+
+ /**
+ * Creates a {@link Builder} using an existing {@link ControlState} as a base.
+ * @param controlState base for the builder.
+ */
+ public Builder(@NonNull ControlState controlState) {
+ Preconditions.checkNotNull(controlState);
+ mControl = controlState.mControl;
+ mControlTemplate = controlState.mControlTemplate;
+ mOverrideIcon = controlState.mOverrideIcon;
+ mStatusText = controlState.mStatusText;
+ mOverrideTint = controlState.mOverrideTint;
+ }
+
+
+ /**
+ * @param control the updated {@link Control} information.
+ * @return {@code this}
+ */
+ @NonNull
+ public Builder setControl(@NonNull Control control) {
+ mControl = control;
+ return this;
+ }
+
+ /**
+ * @param status the current status of the {@link Control}
+ * @return {@code this}
+ */
+ @NonNull
+ public Builder setStatus(@Status int status) {
+ mStatus = status;
+ return this;
+ }
+
+ /**
+ * @param controlTemplate the template to use when rendering the {@code Control}.
+ * @return {@code this}
+ */
+ @NonNull
+ public Builder setControlTemplate(@NonNull ControlTemplate controlTemplate) {
+ Preconditions.checkNotNull(controlTemplate);
+ mControlTemplate = controlTemplate;
+ return this;
+ }
+
+ /**
+ * @param statusText the user-visible description of the status.
+ * @return {@code this}
+ */
+ @NonNull
+ public Builder setStatusText(@NonNull CharSequence statusText) {
+ Preconditions.checkNotNull(statusText);
+ mStatusText = statusText;
+ return this;
+ }
+
+ /**
+ * @param overrideIcon the icon to override the one defined in the corresponding
+ * {@code Control}. Pass {@code null} to remove the override.
+ * @return {@code this}
+ */
+ @NonNull
+ public Builder setOverrideIcon(@Nullable Icon overrideIcon) {
+ mOverrideIcon = overrideIcon;
+ return this;
+ }
+
+ /**
+ * @param overrideTint the colors to override the ones defined in the corresponding
+ * {@code Control}. Pass {@code null} to remove the override.
+ * @return {@code this}
+ */
+ @NonNull
+ public Builder setOverrideTint(@Nullable ColorStateList overrideTint) {
+ mOverrideTint = overrideTint;
+ return this;
+ }
+
+ /**
+ * @return a new {@link ControlState}
+ */
+ public ControlState build() {
+ return new ControlState(mControl, mStatus, mControlTemplate, mStatusText,
+ mOverrideIcon, mOverrideTint);
+ }
+ }
+}
+
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/service/controls/ControlTemplate.aidl
similarity index 81%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/service/controls/ControlTemplate.aidl
index 007ec94..ecb948c 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/service/controls/ControlTemplate.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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.
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.service.controls;
-parcelable WifiActivityEnergyInfo;
+parcelable ControlTemplate;
\ No newline at end of file
diff --git a/core/java/android/service/controls/ControlTemplate.java b/core/java/android/service/controls/ControlTemplate.java
new file mode 100644
index 0000000..e559862
--- /dev/null
+++ b/core/java/android/service/controls/ControlTemplate.java
@@ -0,0 +1,167 @@
+/*
+ * 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 android.service.controls;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An abstract input template for a {@link Control}.
+ *
+ * Specifies what layout is presented to the user when a {@link ControlState} is assigned to a
+ * particular {@link Control}.
+ * <p>
+ * Some instances of {@link Control} can originate actions (via user interaction) to modify its
+ * associated state. The actions available to a given {@link Control} in a particular
+ * {@link ControlState} are determined by its {@link ControlTemplate}.
+ * @see ControlAction
+ * @hide
+ */
+public abstract class ControlTemplate implements Parcelable {
+
+ /**
+ * Singleton representing a {@link Control} with no input.
+ */
+ public static final ControlTemplate NO_TEMPLATE = new ControlTemplate("") {
+ @Override
+ public int getTemplateType() {
+ return TYPE_NONE;
+ }
+ };
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ TYPE_NONE,
+ TYPE_TOGGLE,
+ TYPE_RANGE,
+ TYPE_THUMBNAIL,
+ TYPE_DISCRETE_TOGGLE,
+ TYPE_COORD_RANGE
+ })
+ public @interface TemplateType {}
+
+ /**
+ * Type identifier of {@link ControlTemplate#NO_TEMPLATE}.
+ */
+ public static final int TYPE_NONE = 0;
+
+ /**
+ * Type identifier of {@link ToggleTemplate}.
+ */
+ public static final int TYPE_TOGGLE = 1;
+
+ /**
+ * Type identifier of {@link RangeTemplate}.
+ */
+ public static final int TYPE_RANGE = 2;
+
+ /**
+ * Type identifier of {@link ThumbnailTemplate}.
+ */
+ public static final int TYPE_THUMBNAIL = 3;
+
+ /**
+ * Type identifier of {@link DiscreteToggleTemplate}.
+ */
+ public static final int TYPE_DISCRETE_TOGGLE = 4;
+
+ /**
+ * @hide
+ */
+ public static final int TYPE_COORD_RANGE = 5;
+
+ private @NonNull final String mTemplateId;
+
+ /**
+ * @return the identifier for this object.
+ */
+ public String getTemplateId() {
+ return mTemplateId;
+ }
+
+ /**
+ * The {@link TemplateType} associated with this class.
+ */
+ public abstract @TemplateType int getTemplateType();
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(getTemplateType());
+ dest.writeString(mTemplateId);
+ }
+
+ private ControlTemplate() {
+ mTemplateId = "";
+ }
+
+ ControlTemplate(Parcel in) {
+ mTemplateId = in.readString();
+ }
+
+ /**
+ * @hide
+ */
+ ControlTemplate(@NonNull String templateId) {
+ Preconditions.checkNotNull(templateId);
+ mTemplateId = templateId;
+ }
+
+ public static final Creator<ControlTemplate> CREATOR = new Creator<ControlTemplate>() {
+ @Override
+ public ControlTemplate createFromParcel(Parcel source) {
+ int type = source.readInt();
+ return createTemplateFromType(type, source);
+ }
+
+ @Override
+ public ControlTemplate[] newArray(int size) {
+ return new ControlTemplate[size];
+ }
+ };
+
+ private static ControlTemplate createTemplateFromType(@TemplateType int type, Parcel source) {
+ switch(type) {
+ case TYPE_TOGGLE:
+ return ToggleTemplate.CREATOR.createFromParcel(source);
+ case TYPE_RANGE:
+ return RangeTemplate.CREATOR.createFromParcel(source);
+ case TYPE_THUMBNAIL:
+ return ThumbnailTemplate.CREATOR.createFromParcel(source);
+ case TYPE_DISCRETE_TOGGLE:
+ return DiscreteToggleTemplate.CREATOR.createFromParcel(source);
+ case TYPE_NONE:
+ return NO_TEMPLATE;
+ default:
+ return null;
+ }
+ }
+}
diff --git a/core/java/android/service/controls/DiscreteToggleTemplate.java b/core/java/android/service/controls/DiscreteToggleTemplate.java
new file mode 100644
index 0000000..5167af4
--- /dev/null
+++ b/core/java/android/service/controls/DiscreteToggleTemplate.java
@@ -0,0 +1,110 @@
+/*
+ * 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 android.service.controls;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A template for a {@link Control} with two discrete inputs.
+ *
+ * The two inputs represent a <i>Negative</i> input and a <i>Positive</i> input.
+ * <p>
+ * When one of the buttons is actioned, a {@link BooleanAction} will be sent.
+ * {@link BooleanAction#getNewState} will be {@code false} if the button was
+ * {@link DiscreteToggleTemplate#getNegativeButton} and {@code true} if the button was
+ * {@link DiscreteToggleTemplate#getPositiveButton}.
+ * @hide
+ */
+public class DiscreteToggleTemplate extends ControlTemplate {
+
+ private final @NonNull ControlButton mNegativeButton;
+ private final @NonNull ControlButton mPositiveButton;
+
+ /**
+ * @param templateId the identifier for this template object
+ * @param negativeButton a {@ControlButton} for the <i>Negative</i> input
+ * @param positiveButton a {@ControlButton} for the <i>Positive</i> input
+ */
+ public DiscreteToggleTemplate(@NonNull String templateId,
+ @NonNull ControlButton negativeButton,
+ @NonNull ControlButton positiveButton) {
+ super(templateId);
+ Preconditions.checkNotNull(negativeButton);
+ Preconditions.checkNotNull(positiveButton);
+ mNegativeButton = negativeButton;
+ mPositiveButton = positiveButton;
+ }
+
+ DiscreteToggleTemplate(Parcel in) {
+ super(in);
+ this.mNegativeButton = ControlButton.CREATOR.createFromParcel(in);
+ this.mPositiveButton = ControlButton.CREATOR.createFromParcel(in);
+ }
+
+ /**
+ * The {@link ControlButton} associated with the <i>Negative</i> action.
+ */
+ @NonNull
+ public ControlButton getNegativeButton() {
+ return mNegativeButton;
+ }
+
+ /**
+ * The {@link ControlButton} associated with the <i>Positive</i> action.
+ */
+ @NonNull
+ public ControlButton getPositiveButton() {
+ return mPositiveButton;
+ }
+
+ /**
+ * @return {@link ControlTemplate#TYPE_DISCRETE_TOGGLE}
+ */
+ @Override
+ public int getTemplateType() {
+ return TYPE_DISCRETE_TOGGLE;
+ }
+
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ mNegativeButton.writeToParcel(dest, flags);
+ mPositiveButton.writeToParcel(dest, flags);
+ }
+
+ public static final Creator<DiscreteToggleTemplate> CREATOR =
+ new Creator<DiscreteToggleTemplate>() {
+ @Override
+ public DiscreteToggleTemplate createFromParcel(Parcel source) {
+ return new DiscreteToggleTemplate(source);
+ }
+
+ @Override
+ public DiscreteToggleTemplate[] newArray(int size) {
+ return new DiscreteToggleTemplate[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/service/controls/FloatAction.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/service/controls/FloatAction.aidl
index 007ec94..dbc0f72 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/service/controls/FloatAction.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.service.controls;
-parcelable WifiActivityEnergyInfo;
+parcelable FloatAction;
\ No newline at end of file
diff --git a/core/java/android/service/controls/FloatAction.java b/core/java/android/service/controls/FloatAction.java
new file mode 100644
index 0000000..fe6db10
--- /dev/null
+++ b/core/java/android/service/controls/FloatAction.java
@@ -0,0 +1,90 @@
+/*
+ * 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 android.service.controls;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+
+/**
+ * Action sent by a {@link RangeTemplate}.
+ * @hide
+ */
+public final class FloatAction extends ControlAction {
+
+ private final float mNewValue;
+
+ /**
+ * @param templateId the identifier of the {@link RangeTemplate} that produced this action.
+ * @param newValue new value for the state displayed by the {@link RangeTemplate}.
+ */
+ public FloatAction(@NonNull String templateId, float newValue) {
+ this(templateId, newValue, null);
+ }
+
+ /**
+ * @param templateId the identifier of the {@link RangeTemplate} that originated this action.
+ * @param newValue new value for the state of the {@link RangeTemplate}.
+ * @param challengeValue a value sent by the user along with the action to authenticate. {@code}
+ * null is sent when no authentication is needed or has not been
+ * requested.
+ */
+
+ public FloatAction(@NonNull String templateId, float newValue,
+ @Nullable String challengeValue) {
+ super(templateId, challengeValue);
+ mNewValue = newValue;
+ }
+
+ public FloatAction(Parcel in) {
+ super(in);
+ mNewValue = in.readFloat();
+ }
+
+ /**
+ * The new value set for the range in the corresponding {@link RangeTemplate}.
+ */
+ public float getNewValue() {
+ return mNewValue;
+ }
+
+ /**
+ * @return {@link ControlAction#TYPE_FLOAT}
+ */
+ @Override
+ public int getActionType() {
+ return TYPE_FLOAT;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeFloat(mNewValue);
+ }
+
+ public static final @NonNull Creator<FloatAction> CREATOR = new Creator<FloatAction>() {
+ @Override
+ public FloatAction createFromParcel(Parcel source) {
+ return new FloatAction(source);
+ }
+
+ @Override
+ public FloatAction[] newArray(int size) {
+ return new FloatAction[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/service/controls/IControlsProvider.aidl
similarity index 61%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/service/controls/IControlsProvider.aidl
index 007ec94..f778653 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/service/controls/IControlsProvider.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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.
@@ -14,6 +14,17 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.service.controls;
-parcelable WifiActivityEnergyInfo;
+import android.service.controls.ControlAction;
+
+/** @hide */
+oneway interface IControlsProvider {
+ void load();
+
+ void subscribe(in List<String> controlIds);
+
+ void unsubscribe();
+
+ void onAction(in String controlId, in ControlAction action);
+}
\ No newline at end of file
diff --git a/core/java/android/service/controls/IControlsProviderCallback.aidl b/core/java/android/service/controls/IControlsProviderCallback.aidl
new file mode 100644
index 0000000..3dbb68c
--- /dev/null
+++ b/core/java/android/service/controls/IControlsProviderCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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 android.service.controls;
+
+import android.service.controls.Control;
+import android.service.controls.ControlState;
+
+/** @hide */
+oneway interface IControlsProviderCallback {
+ void onLoad(in List<Control> controls);
+
+ void onRefreshState(in List<ControlState> controlStates);
+
+ void onControlActionResponse(in String controlId, int response);
+}
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/service/controls/RangeTemplate.aidl
similarity index 81%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/service/controls/RangeTemplate.aidl
index 007ec94..a3d1ca0 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/service/controls/RangeTemplate.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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.
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.service.controls;
-parcelable WifiActivityEnergyInfo;
+parcelable RangeTemplate;
\ No newline at end of file
diff --git a/core/java/android/service/controls/RangeTemplate.java b/core/java/android/service/controls/RangeTemplate.java
new file mode 100644
index 0000000..70bf2dd
--- /dev/null
+++ b/core/java/android/service/controls/RangeTemplate.java
@@ -0,0 +1,190 @@
+/*
+ * 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 android.service.controls;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+
+import com.android.internal.util.Preconditions;
+
+import java.security.InvalidParameterException;
+
+/**
+ * A template for a {@link Control} with inputs in a "continuous" range of values.
+ *
+ * @see FloatAction
+ * @hide
+ */
+public final class RangeTemplate extends ControlTemplate {
+
+ private final float mMinValue;
+ private final float mMaxValue;
+ private final float mCurrentValue;
+ private final float mStepValue;
+ private final @NonNull CharSequence mFormatString;
+
+ /**
+ * Construct a new {@link RangeTemplate}.
+ *
+ * The range must be valid, meaning:
+ * <ul>
+ * <li> {@code minValue} < {@code maxValue}
+ * <li> {@code minValue} < {@code currentValue}
+ * <li> {@code currentValue} < {@code maxValue}
+ * <li> 0 < {@code stepValue}
+ * </ul>
+ * <p>
+ * The current value of the Control will be formatted accordingly.
+ *
+ * @param templateId the identifier for this template object
+ * @param minValue minimum value for the input
+ * @param maxValue maximum value for the input
+ * @param currentValue the current value of the {@link ControlState} containing this object.
+ * @param stepValue minimum value of increments/decrements when interacting with this control.
+ * @param formatString a formatting string as per {@link String#format} used to display the
+ * {@code currentValue}. If {@code null} is passed, the "%.1f" is used.
+ * @throws InvalidParameterException if the parameters passed do not make a valid range.
+ */
+ public RangeTemplate(@NonNull String templateId,
+ float minValue,
+ float maxValue,
+ float currentValue,
+ float stepValue,
+ @Nullable CharSequence formatString) {
+ super(templateId);
+ Preconditions.checkNotNull(formatString);
+ mMinValue = minValue;
+ mMaxValue = maxValue;
+ mCurrentValue = currentValue;
+ mStepValue = stepValue;
+ if (formatString != null) {
+ mFormatString = formatString;
+ } else {
+ mFormatString = "%.1f";
+ }
+ validate();
+ }
+
+ /**
+ * Construct a new {@link RangeTemplate} from a {@link Parcel}.
+ *
+ * @throws InvalidParameterException if the parameters passed do not make a valid range
+ * @see RangeTemplate#RangeTemplate(String, float, float, float, float, CharSequence)
+ * @hide
+ */
+ RangeTemplate(Parcel in) {
+ super(in);
+ mMinValue = in.readFloat();
+ mMaxValue = in.readFloat();
+ mCurrentValue = in.readFloat();
+ mStepValue = in.readFloat();
+ mFormatString = in.readCharSequence();
+ validate();
+ }
+
+ /**
+ * The minimum value for this range.
+ */
+ public float getMinValue() {
+ return mMinValue;
+ }
+
+ /**
+ * The maximum value for this range.
+ */
+ public float getMaxValue() {
+ return mMaxValue;
+ }
+
+ /**
+ * The current value for this range.
+ */
+ public float getCurrentValue() {
+ return mCurrentValue;
+ }
+
+ /**
+ * The value of the smallest increment or decrement that can be performed on this range.
+ */
+ public float getStepValue() {
+ return mStepValue;
+ }
+
+ /**
+ * Formatter for generating a user visible {@link String} representing the value
+ * returned by {@link RangeTemplate#getCurrentValue}.
+ * @return a formatting string as specified in {@link String#format}
+ */
+ @NonNull
+ public CharSequence getFormatString() {
+ return mFormatString;
+ }
+
+ /**
+ * @return {@link ControlTemplate#TYPE_RANGE}
+ */
+ @Override
+ public int getTemplateType() {
+ return TYPE_RANGE;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeFloat(mMinValue);
+ dest.writeFloat(mMaxValue);
+ dest.writeFloat(mCurrentValue);
+ dest.writeFloat(mStepValue);
+ dest.writeCharSequence(mFormatString);
+ }
+
+ /**
+ * Validate constructor parameters
+ *
+ * @throws InvalidParameterException if the parameters passed do not make a valid range
+ */
+ private void validate() {
+ if (Float.compare(mMinValue, mMaxValue) > 0) {
+ throw new InvalidParameterException(
+ String.format("minValue=%f > maxValue=%f", mMinValue, mMaxValue));
+ }
+ if (Float.compare(mMinValue, mCurrentValue) > 0) {
+ throw new InvalidParameterException(
+ String.format("minValue=%f > currentValue=%f", mMinValue, mCurrentValue));
+ }
+ if (Float.compare(mCurrentValue, mMaxValue) > 0) {
+ throw new InvalidParameterException(
+ String.format("currentValue=%f > maxValue=%f", mCurrentValue, mMaxValue));
+ }
+ if (mStepValue <= 0) {
+ throw new InvalidParameterException(String.format("stepValue=%f <= 0", mStepValue));
+ }
+ }
+
+ public static final Creator<RangeTemplate> CREATOR = new Creator<RangeTemplate>() {
+ @Override
+ public RangeTemplate createFromParcel(Parcel source) {
+ return new RangeTemplate(source);
+ }
+
+ @Override
+ public RangeTemplate[] newArray(int size) {
+ return new RangeTemplate[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/service/controls/ThumbnailTemplate.aidl
similarity index 81%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/service/controls/ThumbnailTemplate.aidl
index 007ec94..fe8c7fe 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/service/controls/ThumbnailTemplate.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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.
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.service.controls;
-parcelable WifiActivityEnergyInfo;
+parcelable ThumbnailTemplate;
\ No newline at end of file
diff --git a/core/java/android/service/controls/ThumbnailTemplate.java b/core/java/android/service/controls/ThumbnailTemplate.java
new file mode 100644
index 0000000..796d2de
--- /dev/null
+++ b/core/java/android/service/controls/ThumbnailTemplate.java
@@ -0,0 +1,95 @@
+/*
+ * 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 android.service.controls;
+
+import android.annotation.NonNull;
+import android.graphics.drawable.Icon;
+import android.os.Parcel;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A template for a {@link Control} that displays an image.
+ * @hide
+ */
+public final class ThumbnailTemplate extends ControlTemplate {
+
+ private final @NonNull Icon mThumbnail;
+ private final @NonNull CharSequence mContentDescription;
+
+ /**
+ * @param templateId the identifier for this template object
+ * @param thumbnail an image to display on the {@link Control}
+ * @param contentDescription a description of the image for accessibility.
+ */
+ public ThumbnailTemplate(@NonNull String templateId, @NonNull Icon thumbnail,
+ @NonNull CharSequence contentDescription) {
+ super(templateId);
+ Preconditions.checkNotNull(thumbnail);
+ Preconditions.checkNotNull(contentDescription);
+ mThumbnail = thumbnail;
+ mContentDescription = contentDescription;
+ }
+
+ ThumbnailTemplate(Parcel in) {
+ super(in);
+ mThumbnail = Icon.CREATOR.createFromParcel(in);
+ mContentDescription = in.readCharSequence();
+ }
+
+ /**
+ * The {@link Icon} (image) displayed by this template.
+ */
+ @NonNull
+ public Icon getThumbnail() {
+ return mThumbnail;
+ }
+
+ /**
+ * The description of the image returned by {@link ThumbnailTemplate#getThumbnail()}
+ */
+ @NonNull
+ public CharSequence getContentDescription() {
+ return mContentDescription;
+ }
+
+ /**
+ * @return {@link ControlTemplate#TYPE_THUMBNAIL}
+ */
+ @Override
+ public int getTemplateType() {
+ return TYPE_THUMBNAIL;
+ }
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ mThumbnail.writeToParcel(dest, flags);
+ dest.writeCharSequence(mContentDescription);
+ }
+
+ public static final Creator<ThumbnailTemplate> CREATOR = new Creator<ThumbnailTemplate>() {
+ @Override
+ public ThumbnailTemplate createFromParcel(Parcel source) {
+ return new ThumbnailTemplate(source);
+ }
+
+ @Override
+ public ThumbnailTemplate[] newArray(int size) {
+ return new ThumbnailTemplate[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/core/java/android/service/controls/ToggleTemplate.aidl
similarity index 81%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to core/java/android/service/controls/ToggleTemplate.aidl
index 007ec94..1c823d9 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/core/java/android/service/controls/ToggleTemplate.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * 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.
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.service.controls;
-parcelable WifiActivityEnergyInfo;
+parcelable ToggleTemplate;
\ No newline at end of file
diff --git a/core/java/android/service/controls/ToggleTemplate.java b/core/java/android/service/controls/ToggleTemplate.java
new file mode 100644
index 0000000..3766bd1
--- /dev/null
+++ b/core/java/android/service/controls/ToggleTemplate.java
@@ -0,0 +1,86 @@
+/*
+ * 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 android.service.controls;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A template for a {@link Control} with a single button that can be toggled between two states.
+ *
+ * The states for the toggle correspond to the states in {@link ControlButton#isActive()}.
+ * An action on this template will originate a {@link BooleanAction} to change that state.
+ *
+ * @see BooleanAction
+ * @hide
+ */
+public final class ToggleTemplate extends ControlTemplate {
+
+ private final @NonNull ControlButton mButton;
+
+ /**
+ * @param templateId the identifier for this template object
+ * @param button a {@ControlButton} that can show the current state and toggle it
+ */
+ public ToggleTemplate(@NonNull String templateId, @NonNull ControlButton button) {
+ super(templateId);
+ Preconditions.checkNotNull(button);
+ mButton = button;
+ }
+
+ ToggleTemplate(Parcel in) {
+ super(in);
+ mButton = ControlButton.CREATOR.createFromParcel(in);
+ }
+
+ /**
+ * The button provided to this object in {@link ToggleTemplate#ToggleTemplate}
+ */
+ @NonNull
+ public ControlButton getButton() {
+ return mButton;
+ }
+
+ /**
+ * @return {@link ControlTemplate#TYPE_TOGGLE}
+ */
+ @Override
+ public int getTemplateType() {
+ return TYPE_TOGGLE;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ mButton.writeToParcel(dest, flags);
+ }
+
+ public static final Creator<ToggleTemplate> CREATOR = new Creator<ToggleTemplate>() {
+ @Override
+ public ToggleTemplate createFromParcel(Parcel source) {
+ return new ToggleTemplate(source);
+ }
+
+ @Override
+ public ToggleTemplate[] newArray(int size) {
+ return new ToggleTemplate[size];
+ }
+ };
+
+}
diff --git a/core/java/android/service/incremental/IIncrementalDataLoaderService.aidl b/core/java/android/service/incremental/IIncrementalDataLoaderService.aidl
deleted file mode 100644
index 723fc59..0000000
--- a/core/java/android/service/incremental/IIncrementalDataLoaderService.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.incremental;
-
-import android.os.incremental.IncrementalDataLoaderParamsParcel;
-import android.os.incremental.IncrementalFileSystemControlParcel;
-import android.service.incremental.IIncrementalDataLoaderStatusListener;
-
-/** @hide */
-oneway interface IIncrementalDataLoaderService {
- void createDataLoader(in int storageId,
- in IncrementalFileSystemControlParcel control,
- in IncrementalDataLoaderParamsParcel params,
- in IIncrementalDataLoaderStatusListener listener,
- in boolean start);
- void startDataLoader(in int storageId);
- void stopDataLoader(in int storageId);
- void destroyDataLoader(in int storageId);
- void onFileCreated(in int storageId, in long inode, in byte[] metadata);
-}
diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java
index e506509..cf57e25 100644
--- a/core/java/android/service/notification/Condition.java
+++ b/core/java/android/service/notification/Condition.java
@@ -151,7 +151,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
// id is guaranteed not to be null.
diff --git a/core/java/android/service/notification/IConditionProvider.aidl b/core/java/android/service/notification/IConditionProvider.aidl
index 3f3c6b8..dd3904f 100644
--- a/core/java/android/service/notification/IConditionProvider.aidl
+++ b/core/java/android/service/notification/IConditionProvider.aidl
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2014, The Android Open Source Project
+ * 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.
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 1f2c872..dedc3b7 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -1739,7 +1739,7 @@
/** @hide */
// TODO: add configuration activity
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(ZenRuleProto.ID, id);
@@ -1753,13 +1753,13 @@
proto.write(ZenRuleProto.CONDITION_ID, conditionId.toString());
}
if (condition != null) {
- condition.writeToProto(proto, ZenRuleProto.CONDITION);
+ condition.dumpDebug(proto, ZenRuleProto.CONDITION);
}
if (component != null) {
- component.writeToProto(proto, ZenRuleProto.COMPONENT);
+ component.dumpDebug(proto, ZenRuleProto.COMPONENT);
}
if (zenPolicy != null) {
- zenPolicy.writeToProto(proto, ZenRuleProto.ZEN_POLICY);
+ zenPolicy.dumpDebug(proto, ZenRuleProto.ZEN_POLICY);
}
proto.write(ZenRuleProto.MODIFIED, modified);
proto.end(token);
diff --git a/core/java/android/service/notification/ZenPolicy.java b/core/java/android/service/notification/ZenPolicy.java
index 9694998..6e2faa9 100644
--- a/core/java/android/service/notification/ZenPolicy.java
+++ b/core/java/android/service/notification/ZenPolicy.java
@@ -973,7 +973,7 @@
/**
* @hide
*/
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(ZenPolicyProto.REMINDERS, getPriorityCategoryReminders());
diff --git a/telephony/java/android/telephony/DataConnectionRealTimeInfo.aidl b/core/java/android/telephony/DataConnectionRealTimeInfo.aidl
similarity index 100%
rename from telephony/java/android/telephony/DataConnectionRealTimeInfo.aidl
rename to core/java/android/telephony/DataConnectionRealTimeInfo.aidl
diff --git a/telephony/java/android/telephony/DataConnectionRealTimeInfo.java b/core/java/android/telephony/DataConnectionRealTimeInfo.java
similarity index 100%
rename from telephony/java/android/telephony/DataConnectionRealTimeInfo.java
rename to core/java/android/telephony/DataConnectionRealTimeInfo.java
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index f66a679..9d7b57b 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -455,6 +455,19 @@
}
/**
+ * Sim activation type: voice
+ * @see #notifyVoiceActivationStateChanged
+ * @hide
+ */
+ public static final int SIM_ACTIVATION_TYPE_VOICE = 0;
+ /**
+ * Sim activation type: data
+ * @see #notifyDataActivationStateChanged
+ * @hide
+ */
+ public static final int SIM_ACTIVATION_TYPE_DATA = 1;
+
+ /**
* Notify data activation state changed on certain subscription.
* @see TelephonyManager#getDataActivationState()
*
@@ -469,7 +482,7 @@
@SimActivationState int activationState) {
try {
sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId,
- TelephonyManager.SIM_ACTIVATION_TYPE_DATA, activationState);
+ SIM_ACTIVATION_TYPE_DATA, activationState);
} catch (RemoteException ex) {
// system process is dead
}
@@ -490,7 +503,7 @@
@SimActivationState int activationState) {
try {
sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId,
- TelephonyManager.SIM_ACTIVATION_TYPE_VOICE, activationState);
+ SIM_ACTIVATION_TYPE_VOICE, activationState);
} catch (RemoteException ex) {
// system process is dead
}
diff --git a/core/java/android/util/StatsEvent.java b/core/java/android/util/StatsEvent.java
index d7ec30c..0a4069d 100644
--- a/core/java/android/util/StatsEvent.java
+++ b/core/java/android/util/StatsEvent.java
@@ -177,7 +177,7 @@
* @hide
**/
@VisibleForTesting
- public static final int ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL = 0x400;
+ public static final int ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL = 0x1000;
// Size limits.
@@ -628,9 +628,9 @@
if (0 == mErrorMask) {
mBuffer.putByte(POS_NUM_ELEMENTS, (byte) mNumElements);
} else {
- mBuffer.putByte(0, TYPE_ERRORS);
- mBuffer.putByte(POS_NUM_ELEMENTS, (byte) 3);
+ mPos += mBuffer.putByte(mPos, TYPE_ERRORS);
mPos += mBuffer.putInt(mPos, mErrorMask);
+ mBuffer.putByte(POS_NUM_ELEMENTS, (byte) 3);
size = mPos;
}
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 797c128..411508f 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -500,13 +500,13 @@
/**
* @hide
*/
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- mSafeInsets.writeToProto(proto, INSETS);
- mBounds.getRect(BOUNDS_POSITION_LEFT).writeToProto(proto, BOUND_LEFT);
- mBounds.getRect(BOUNDS_POSITION_TOP).writeToProto(proto, BOUND_TOP);
- mBounds.getRect(BOUNDS_POSITION_RIGHT).writeToProto(proto, BOUND_RIGHT);
- mBounds.getRect(BOUNDS_POSITION_BOTTOM).writeToProto(proto, BOUND_BOTTOM);
+ mSafeInsets.dumpDebug(proto, INSETS);
+ mBounds.getRect(BOUNDS_POSITION_LEFT).dumpDebug(proto, BOUND_LEFT);
+ mBounds.getRect(BOUNDS_POSITION_TOP).dumpDebug(proto, BOUND_TOP);
+ mBounds.getRect(BOUNDS_POSITION_RIGHT).dumpDebug(proto, BOUND_RIGHT);
+ mBounds.getRect(BOUNDS_POSITION_BOTTOM).dumpDebug(proto, BOUND_BOTTOM);
proto.end(token);
}
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 38baccb..04e82c7 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -651,7 +651,7 @@
* @param protoOutputStream Stream to write the Rect object to.
* @param fieldId Field Id of the DisplayInfoProto as defined in the parent message
*/
- public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
+ public void dumpDebug(ProtoOutputStream protoOutputStream, long fieldId) {
final long token = protoOutputStream.start(fieldId);
protoOutputStream.write(LOGICAL_WIDTH, logicalWidth);
protoOutputStream.write(LOGICAL_HEIGHT, logicalHeight);
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 3c93bb7..bc70d63 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -467,6 +467,10 @@
}
}
+ boolean isAnimating() {
+ return mAnimationDirection != DIRECTION_NONE;
+ }
+
private InsetsSourceConsumer createConsumerOfType(int type) {
if (type == ITYPE_IME) {
return new ImeInsetsSourceConsumer(mState, Transaction::new, this);
@@ -514,6 +518,7 @@
} else {
hideDirectly(types);
}
+ mAnimationDirection = show ? DIRECTION_SHOW : DIRECTION_HIDE;
mAnimator = ObjectAnimator.ofObject(
controller,
new InsetsProperty(),
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index b1caf18..c6d9898 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -167,7 +167,8 @@
}
private void applyHiddenToControl() {
- if (mSourceControl == null || mSourceControl.getLeash() == null) {
+ if (mSourceControl == null || mSourceControl.getLeash() == null
+ || mController.isAnimating()) {
return;
}
diff --git a/core/java/android/view/RemoteAnimationTarget.java b/core/java/android/view/RemoteAnimationTarget.java
index ae3e1d0..b873482 100644
--- a/core/java/android/view/RemoteAnimationTarget.java
+++ b/core/java/android/view/RemoteAnimationTarget.java
@@ -234,23 +234,23 @@
pw.print(prefix); pw.print("leash="); pw.println(leash);
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(TASK_ID, taskId);
proto.write(MODE, mode);
- leash.writeToProto(proto, LEASH);
+ leash.dumpDebug(proto, LEASH);
proto.write(IS_TRANSLUCENT, isTranslucent);
- clipRect.writeToProto(proto, CLIP_RECT);
- contentInsets.writeToProto(proto, CONTENT_INSETS);
+ clipRect.dumpDebug(proto, CLIP_RECT);
+ contentInsets.dumpDebug(proto, CONTENT_INSETS);
proto.write(PREFIX_ORDER_INDEX, prefixOrderIndex);
- position.writeToProto(proto, POSITION);
- sourceContainerBounds.writeToProto(proto, SOURCE_CONTAINER_BOUNDS);
- windowConfiguration.writeToProto(proto, WINDOW_CONFIGURATION);
+ position.dumpDebug(proto, POSITION);
+ sourceContainerBounds.dumpDebug(proto, SOURCE_CONTAINER_BOUNDS);
+ windowConfiguration.dumpDebug(proto, WINDOW_CONFIGURATION);
if (startLeash != null) {
- startLeash.writeToProto(proto, START_LEASH);
+ startLeash.dumpDebug(proto, START_LEASH);
}
if (startBounds != null) {
- startBounds.writeToProto(proto, START_BOUNDS);
+ startBounds.dumpDebug(proto, START_BOUNDS);
}
proto.end(token);
}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index fc80e00..87628da 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -442,6 +442,12 @@
public static final int METADATA_TASK_ID = 3;
/**
+ * Accessibility ID to allow association between surfaces and accessibility tree.
+ * @hide
+ */
+ public static final int METADATA_ACCESSIBILITY_ID = 4;
+
+ /**
* A wrapper around GraphicBuffer that contains extra information about how to
* interpret the screenshot GraphicBuffer.
* @hide
@@ -895,7 +901,7 @@
* @param fieldId Field Id of the SurfaceControl as defined in the parent message.
* @hide
*/
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(HASH_CODE, System.identityHashCode(this));
proto.write(NAME, mName);
@@ -2651,6 +2657,7 @@
* @hide
*/
public Transaction setMetadata(SurfaceControl sc, int key, Parcel data) {
+ sc.checkNotReleased();
nativeSetMetadata(mNativeObject, sc.mNativeObject, key, data);
return this;
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c62e69c..d40f832 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1181,7 +1181,8 @@
* a soft input method, so it will be Z-ordered and positioned
* independently of any active input method (typically this means it
* gets Z-ordered on top of the input method, so it can use the full
- * screen for its content and cover the input method if needed.) */
+ * screen for its content and cover the input method if needed. You
+ * can use {@link #FLAG_ALT_FOCUSABLE_IM} to modify this behavior. */
public static final int FLAG_NOT_FOCUSABLE = 0x00000008;
/** Window flag: this window can never receive touch events. */
@@ -1287,11 +1288,14 @@
* set for you by Window as described in {@link Window#setFlags}.*/
public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000;
- /** Window flag: When set, input method can't interact with the focusable window
- * and can be placed to use more space and cover the input method.
- * Note: When combined with {@link #FLAG_NOT_FOCUSABLE}, this flag has no
- * effect since input method cannot interact with windows having {@link #FLAG_NOT_FOCUSABLE}
- * flag set.
+ /** Window flag: invert the state of {@link #FLAG_NOT_FOCUSABLE} with
+ * respect to how this window interacts with the current method. That
+ * is, if FLAG_NOT_FOCUSABLE is set and this flag is set, then the
+ * window will behave as if it needs to interact with the input method
+ * and thus be placed behind/away from it; if FLAG_NOT_FOCUSABLE is
+ * not set and this flag is set, then the window will behave as if it
+ * doesn't need to interact with the input method and can be placed
+ * to use more space and cover the input method.
*/
public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000;
@@ -1989,12 +1993,16 @@
*
* @param flags The current window manager flags.
*
- * @return Returns {@code true} if such a window should be behind/interact
- * with an input method, (@code false} if not.
+ * @return Returns true if such a window should be behind/interact
+ * with an input method, false if not.
*/
public static boolean mayUseInputMethod(int flags) {
- return (flags & FLAG_NOT_FOCUSABLE) != FLAG_NOT_FOCUSABLE
- && (flags & FLAG_ALT_FOCUSABLE_IM) != FLAG_ALT_FOCUSABLE_IM;
+ switch (flags&(FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
+ case 0:
+ case FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM:
+ return true;
+ }
+ return false;
}
/**
@@ -3251,7 +3259,7 @@
/**
* @hide
*/
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(TYPE, type);
proto.write(X, x);
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 54446e1..9c04b39 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -47,6 +47,7 @@
import android.service.autofill.AutofillService;
import android.service.autofill.FillEventHistory;
import android.service.autofill.UserData;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
@@ -61,6 +62,7 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.accessibility.AccessibilityWindowInfo;
+import android.widget.EditText;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
@@ -1073,6 +1075,8 @@
} else if (sVerbose) {
Log.v(TAG, "Ignoring visibility change on " + id + ": no tracked views");
}
+ } else if (!virtual && isVisible) {
+ startAutofillIfNeededLocked(view);
}
}
}
@@ -1238,9 +1242,11 @@
return;
}
if (!mEnabled || !isActiveLocked()) {
- if (sVerbose) {
- Log.v(TAG, "notifyValueChanged(" + view.getAutofillId()
- + "): ignoring on state " + getStateAsStringLocked());
+ if (!startAutofillIfNeededLocked(view)) {
+ if (sVerbose) {
+ Log.v(TAG, "notifyValueChanged(" + view.getAutofillId()
+ + "): ignoring on state " + getStateAsStringLocked());
+ }
}
return;
}
@@ -1879,6 +1885,37 @@
}
}
+ @GuardedBy("mLock")
+ private boolean startAutofillIfNeededLocked(View view) {
+ if (mState == STATE_UNKNOWN
+ && mSessionId == NO_SESSION
+ && view instanceof EditText
+ && !TextUtils.isEmpty(((EditText) view).getText())
+ && !view.isFocused()
+ && view.isImportantForAutofill()
+ && view.isLaidOut()
+ && view.isVisibleToUser()) {
+
+ ensureServiceClientAddedIfNeededLocked();
+
+ if (sVerbose) {
+ Log.v(TAG, "startAutofillIfNeededLocked(): enabled=" + mEnabled);
+ }
+ if (mEnabled && !isClientDisablingEnterExitEvent()) {
+ final AutofillId id = view.getAutofillId();
+ final AutofillValue value = view.getAutofillValue();
+ // Starts new session.
+ startSessionLocked(id, /* bounds= */ null, /* value= */ null, /* flags= */ 0);
+ // Updates value.
+ updateSessionLocked(id, /* bounds= */ null, value, ACTION_VALUE_CHANGED,
+ /* flags= */ 0);
+ addEnteredIdLocked(id);
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Registers a {@link AutofillCallback} to receive autofill events.
*
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 187ab46..eb0d9bf 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -152,6 +152,9 @@
// handles.
private static final boolean FLAG_USE_MAGNIFIER = true;
+ private static final int DELAY_BEFORE_HANDLE_FADES_OUT = 4000;
+ private static final int RECENT_CUT_COPY_DURATION_MS = 15 * 1000; // 15 seconds in millis
+
static final int BLINK = 500;
private static final int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
private static final float LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS = 0.5f;
@@ -326,8 +329,6 @@
// Global listener that detects changes in the global position of the TextView
private PositionListener mPositionListener;
- private float mLastDownPositionX, mLastDownPositionY;
- private float mLastUpPositionX, mLastUpPositionY;
private float mContextMenuAnchorX, mContextMenuAnchorY;
Callback mCustomSelectionActionModeCallback;
Callback mCustomInsertionActionModeCallback;
@@ -336,18 +337,11 @@
@UnsupportedAppUsage
boolean mCreatedWithASelection;
- // Indicates the current tap state (first tap, double tap, or triple click).
- private int mTapState = TAP_STATE_INITIAL;
- private long mLastTouchUpTime = 0;
- private static final int TAP_STATE_INITIAL = 0;
- private static final int TAP_STATE_FIRST_TAP = 1;
- private static final int TAP_STATE_DOUBLE_TAP = 2;
- // Only for mouse input.
- private static final int TAP_STATE_TRIPLE_CLICK = 3;
-
// The button state as of the last time #onTouchEvent is called.
private int mLastButtonState;
+ private final EditorTouchState mTouchState = new EditorTouchState();
+
private Runnable mInsertionActionModeRunnable;
// The span controller helps monitoring the changes to which the Editor needs to react:
@@ -1193,10 +1187,10 @@
logCursor("performLongClick", "handled=%s", handled);
}
// Long press in empty space moves cursor and starts the insertion action mode.
- if (!handled && !isPositionOnText(mLastDownPositionX, mLastDownPositionY)
+ if (!handled && !isPositionOnText(mTouchState.getLastDownX(), mTouchState.getLastDownY())
&& mInsertionControllerEnabled) {
- final int offset = mTextView.getOffsetForPosition(mLastDownPositionX,
- mLastDownPositionY);
+ final int offset = mTextView.getOffsetForPosition(mTouchState.getLastDownX(),
+ mTouchState.getLastDownY());
Selection.setSelection((Spannable) mTextView.getText(), offset);
getInsertionController().show();
mIsInsertionActionModeStartPending = true;
@@ -1240,11 +1234,11 @@
}
float getLastUpPositionX() {
- return mLastUpPositionX;
+ return mTouchState.getLastUpX();
}
float getLastUpPositionY() {
- return mLastUpPositionY;
+ return mTouchState.getLastUpY();
}
private long getLastTouchOffsets() {
@@ -1279,6 +1273,9 @@
// Has to be done before onTakeFocus, which can be overloaded.
final int lastTapPosition = getLastTapPosition();
if (lastTapPosition >= 0) {
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("onFocusChanged", "setting cursor position: %d", lastTapPosition);
+ }
Selection.setSelection((Spannable) mTextView.getText(), lastTapPosition);
}
@@ -1443,39 +1440,6 @@
}
}
- private void updateTapState(MotionEvent event) {
- final int action = event.getActionMasked();
- if (action == MotionEvent.ACTION_DOWN) {
- final boolean isMouse = event.isFromSource(InputDevice.SOURCE_MOUSE);
- // Detect double tap and triple click.
- if (((mTapState == TAP_STATE_FIRST_TAP)
- || ((mTapState == TAP_STATE_DOUBLE_TAP) && isMouse))
- && (SystemClock.uptimeMillis() - mLastTouchUpTime)
- <= ViewConfiguration.getDoubleTapTimeout()) {
- if (mTapState == TAP_STATE_FIRST_TAP) {
- mTapState = TAP_STATE_DOUBLE_TAP;
- } else {
- mTapState = TAP_STATE_TRIPLE_CLICK;
- }
- if (TextView.DEBUG_CURSOR) {
- logCursor("updateTapState", "ACTION_DOWN: %s tap detected",
- (mTapState == TAP_STATE_DOUBLE_TAP ? "double" : "triple"));
- }
- } else {
- mTapState = TAP_STATE_FIRST_TAP;
- if (TextView.DEBUG_CURSOR) {
- logCursor("updateTapState", "ACTION_DOWN: first tap detected");
- }
- }
- }
- if (action == MotionEvent.ACTION_UP) {
- mLastTouchUpTime = SystemClock.uptimeMillis();
- if (TextView.DEBUG_CURSOR) {
- logCursor("updateTapState", "ACTION_UP");
- }
- }
- }
-
private boolean shouldFilterOutTouchEvent(MotionEvent event) {
if (!event.isFromSource(InputDevice.SOURCE_MOUSE)) {
return false;
@@ -1503,7 +1467,8 @@
}
return;
}
- updateTapState(event);
+ ViewConfiguration viewConfiguration = ViewConfiguration.get(mTextView.getContext());
+ mTouchState.update(event, viewConfiguration);
updateFloatingToolbarVisibility(event);
if (hasSelectionController()) {
@@ -1515,15 +1480,7 @@
mShowSuggestionRunnable = null;
}
- if (event.getActionMasked() == MotionEvent.ACTION_UP) {
- mLastUpPositionX = event.getX();
- mLastUpPositionY = event.getY();
- }
-
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
- mLastDownPositionX = event.getX();
- mLastDownPositionY = event.getY();
-
// Reset this state; it will be re-set if super.onTouchEvent
// causes focus to move to the view.
mTouchFocusSelected = false;
@@ -5067,7 +5024,10 @@
public boolean onTouchEvent(MotionEvent ev) {
if (TextView.DEBUG_CURSOR) {
logCursor(this.getClass().getSimpleName() + ": HandleView: onTouchEvent",
- MotionEvent.actionToString(ev.getActionMasked()));
+ "%d: %s (%f,%f)",
+ ev.getSequenceNumber(),
+ MotionEvent.actionToString(ev.getActionMasked()),
+ ev.getX(), ev.getY());
}
updateFloatingToolbarVisibility(ev);
@@ -5145,56 +5105,14 @@
}
private class InsertionHandleView extends HandleView {
- private static final int DELAY_BEFORE_HANDLE_FADES_OUT = 4000;
- private static final int RECENT_CUT_COPY_DURATION = 15 * 1000; // seconds
-
// Used to detect taps on the insertion handle, which will affect the insertion action mode
- private float mDownPositionX, mDownPositionY;
+ private float mLastDownRawX, mLastDownRawY;
private Runnable mHider;
public InsertionHandleView(Drawable drawable) {
super(drawable, drawable, com.android.internal.R.id.insertion_handle);
}
- @Override
- public void show() {
- super.show();
-
- final long durationSinceCutOrCopy =
- SystemClock.uptimeMillis() - TextView.sLastCutCopyOrTextChangedTime;
-
- // Cancel the single tap delayed runnable.
- if (mInsertionActionModeRunnable != null
- && ((mTapState == TAP_STATE_DOUBLE_TAP)
- || (mTapState == TAP_STATE_TRIPLE_CLICK)
- || isCursorInsideEasyCorrectionSpan())) {
- mTextView.removeCallbacks(mInsertionActionModeRunnable);
- }
-
- // Prepare and schedule the single tap runnable to run exactly after the double tap
- // timeout has passed.
- if ((mTapState != TAP_STATE_DOUBLE_TAP) && (mTapState != TAP_STATE_TRIPLE_CLICK)
- && !isCursorInsideEasyCorrectionSpan()
- && (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION)) {
- if (mTextActionMode == null) {
- if (mInsertionActionModeRunnable == null) {
- mInsertionActionModeRunnable = new Runnable() {
- @Override
- public void run() {
- startInsertionActionMode();
- }
- };
- }
- mTextView.postDelayed(
- mInsertionActionModeRunnable,
- ViewConfiguration.getDoubleTapTimeout() + 1);
- }
-
- }
-
- hideAfterDelay();
- }
-
private void hideAfterDelay() {
if (mHider == null) {
mHider = new Runnable() {
@@ -5250,8 +5168,8 @@
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
- mDownPositionX = ev.getRawX();
- mDownPositionY = ev.getRawY();
+ mLastDownRawX = ev.getRawX();
+ mLastDownRawY = ev.getRawY();
updateMagnifier(ev);
break;
@@ -5261,8 +5179,8 @@
case MotionEvent.ACTION_UP:
if (!offsetHasBeenChanged()) {
- final float deltaX = mDownPositionX - ev.getRawX();
- final float deltaY = mDownPositionY - ev.getRawY();
+ final float deltaX = mLastDownRawX - ev.getRawX();
+ final float deltaY = mLastDownRawY - ev.getRawY();
final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
final ViewConfiguration viewConfiguration = ViewConfiguration.get(
@@ -5804,6 +5722,37 @@
public void show() {
getHandle().show();
+ final long durationSinceCutOrCopy =
+ SystemClock.uptimeMillis() - TextView.sLastCutCopyOrTextChangedTime;
+
+ // Cancel the single tap delayed runnable.
+ if (mInsertionActionModeRunnable != null
+ && (mTouchState.isMultiTap() || isCursorInsideEasyCorrectionSpan())) {
+ mTextView.removeCallbacks(mInsertionActionModeRunnable);
+ }
+
+ // Prepare and schedule the single tap runnable to run exactly after the double tap
+ // timeout has passed.
+ if (!mTouchState.isMultiTap()
+ && !isCursorInsideEasyCorrectionSpan()
+ && (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION_MS)) {
+ if (mTextActionMode == null) {
+ if (mInsertionActionModeRunnable == null) {
+ mInsertionActionModeRunnable = new Runnable() {
+ @Override
+ public void run() {
+ startInsertionActionMode();
+ }
+ };
+ }
+ mTextView.postDelayed(
+ mInsertionActionModeRunnable,
+ ViewConfiguration.getDoubleTapTimeout() + 1);
+ }
+ }
+
+ getHandle().hideAfterDelay();
+
if (mSelectionModifierCursorController != null) {
mSelectionModifierCursorController.hide();
}
@@ -5870,7 +5819,6 @@
// The offsets of that last touch down event. Remembered to start selection there.
private int mMinTouchOffset, mMaxTouchOffset;
- private float mDownPositionX, mDownPositionY;
private boolean mGestureStayedInTapRegion;
// Where the user first starts the drag motion.
@@ -5940,13 +5888,18 @@
}
public void enterDrag(int dragAcceleratorMode) {
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("SelectionModifierCursorController: enterDrag",
+ "starting selection drag: mode=%s", dragAcceleratorMode);
+ }
+
// Just need to init the handles / hide insertion cursor.
show();
mDragAcceleratorMode = dragAcceleratorMode;
// Start location of selection.
- mStartOffset = mTextView.getOffsetForPosition(mLastDownPositionX,
- mLastDownPositionY);
- mLineSelectionIsOn = mTextView.getLineAtCoordinate(mLastDownPositionY);
+ mStartOffset = mTextView.getOffsetForPosition(mTouchState.getLastDownX(),
+ mTouchState.getLastDownY());
+ mLineSelectionIsOn = mTextView.getLineAtCoordinate(mTouchState.getLastDownY());
// Don't show the handles until user has lifted finger.
hide();
@@ -5974,36 +5927,20 @@
eventX, eventY);
// Double tap detection
- if (mGestureStayedInTapRegion) {
- if (mTapState == TAP_STATE_DOUBLE_TAP
- || mTapState == TAP_STATE_TRIPLE_CLICK) {
- final float deltaX = eventX - mDownPositionX;
- final float deltaY = eventY - mDownPositionY;
- final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
-
- ViewConfiguration viewConfiguration = ViewConfiguration.get(
- mTextView.getContext());
- int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop();
- boolean stayedInArea =
- distanceSquared < doubleTapSlop * doubleTapSlop;
-
- if (stayedInArea && (isMouse || isPositionOnText(eventX, eventY))) {
- if (TextView.DEBUG_CURSOR) {
- logCursor("SelectionModifierCursorController: onTouchEvent",
- "ACTION_DOWN: select and start drag");
- }
- if (mTapState == TAP_STATE_DOUBLE_TAP) {
- selectCurrentWordAndStartDrag();
- } else if (mTapState == TAP_STATE_TRIPLE_CLICK) {
- selectCurrentParagraphAndStartDrag();
- }
- mDiscardNextActionUp = true;
- }
+ if (mGestureStayedInTapRegion
+ && mTouchState.isMultiTapInSameArea()
+ && (isMouse || isPositionOnText(eventX, eventY))) {
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("SelectionModifierCursorController: onTouchEvent",
+ "ACTION_DOWN: select and start drag");
}
+ if (mTouchState.isDoubleTap()) {
+ selectCurrentWordAndStartDrag();
+ } else if (mTouchState.isTripleClick()) {
+ selectCurrentParagraphAndStartDrag();
+ }
+ mDiscardNextActionUp = true;
}
-
- mDownPositionX = eventX;
- mDownPositionY = eventY;
mGestureStayedInTapRegion = true;
mHaventMovedEnoughToStartDrag = true;
}
@@ -6025,8 +5962,8 @@
final int touchSlop = viewConfig.getScaledTouchSlop();
if (mGestureStayedInTapRegion || mHaventMovedEnoughToStartDrag) {
- final float deltaX = eventX - mDownPositionX;
- final float deltaY = eventY - mDownPositionY;
+ final float deltaX = eventX - mTouchState.getLastDownX();
+ final float deltaY = eventY - mTouchState.getLastDownY();
final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
if (mGestureStayedInTapRegion) {
@@ -7164,7 +7101,7 @@
}
}
- private static void logCursor(String location, @Nullable String msgFormat, Object ... msgArgs) {
+ static void logCursor(String location, @Nullable String msgFormat, Object ... msgArgs) {
if (msgFormat == null) {
Log.d(TAG, location);
} else {
diff --git a/core/java/android/widget/EditorTouchState.java b/core/java/android/widget/EditorTouchState.java
new file mode 100644
index 0000000..f880939
--- /dev/null
+++ b/core/java/android/widget/EditorTouchState.java
@@ -0,0 +1,137 @@
+/*
+ * 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 android.widget;
+
+import static android.widget.Editor.logCursor;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
+import android.annotation.IntDef;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Helper class used by {@link Editor} to track state for touch events.
+ *
+ * @hide
+ */
+@VisibleForTesting(visibility = PACKAGE)
+public class EditorTouchState {
+ private float mLastDownX, mLastDownY;
+ private float mLastUpX, mLastUpY;
+ private long mLastUpMillis;
+
+ @IntDef({MultiTapStatus.NONE, MultiTapStatus.FIRST_TAP, MultiTapStatus.DOUBLE_TAP,
+ MultiTapStatus.TRIPLE_CLICK})
+ @Retention(RetentionPolicy.SOURCE)
+ @VisibleForTesting
+ public @interface MultiTapStatus {
+ int NONE = 0;
+ int FIRST_TAP = 1;
+ int DOUBLE_TAP = 2;
+ int TRIPLE_CLICK = 3; // Only for mouse input.
+ }
+ @MultiTapStatus
+ private int mMultiTapStatus = MultiTapStatus.NONE;
+ private boolean mMultiTapInSameArea;
+
+ public float getLastDownX() {
+ return mLastDownX;
+ }
+
+ public float getLastDownY() {
+ return mLastDownY;
+ }
+
+ public float getLastUpX() {
+ return mLastUpX;
+ }
+
+ public float getLastUpY() {
+ return mLastUpY;
+ }
+
+ public boolean isDoubleTap() {
+ return mMultiTapStatus == MultiTapStatus.DOUBLE_TAP;
+ }
+
+ public boolean isTripleClick() {
+ return mMultiTapStatus == MultiTapStatus.TRIPLE_CLICK;
+ }
+
+ public boolean isMultiTap() {
+ return mMultiTapStatus == MultiTapStatus.DOUBLE_TAP
+ || mMultiTapStatus == MultiTapStatus.TRIPLE_CLICK;
+ }
+
+ public boolean isMultiTapInSameArea() {
+ return isMultiTap() && mMultiTapInSameArea;
+ }
+
+ /**
+ * Updates the state based on the new event.
+ */
+ public void update(MotionEvent event, ViewConfiguration viewConfiguration) {
+ final int action = event.getActionMasked();
+ if (action == MotionEvent.ACTION_DOWN) {
+ final boolean isMouse = event.isFromSource(InputDevice.SOURCE_MOUSE);
+ final long millisSinceLastUp = event.getEventTime() - mLastUpMillis;
+ // Detect double tap and triple click.
+ if (millisSinceLastUp <= ViewConfiguration.getDoubleTapTimeout()
+ && (mMultiTapStatus == MultiTapStatus.FIRST_TAP
+ || (mMultiTapStatus == MultiTapStatus.DOUBLE_TAP && isMouse))) {
+ if (mMultiTapStatus == MultiTapStatus.FIRST_TAP) {
+ mMultiTapStatus = MultiTapStatus.DOUBLE_TAP;
+ } else {
+ mMultiTapStatus = MultiTapStatus.TRIPLE_CLICK;
+ }
+ final float deltaX = event.getX() - mLastDownX;
+ final float deltaY = event.getY() - mLastDownY;
+ final int distanceSquared = (int) ((deltaX * deltaX) + (deltaY * deltaY));
+ int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop();
+ mMultiTapInSameArea = distanceSquared < doubleTapSlop * doubleTapSlop;
+ if (TextView.DEBUG_CURSOR) {
+ String status = isDoubleTap() ? "double" : "triple";
+ String inSameArea = mMultiTapInSameArea ? "in same area" : "not in same area";
+ logCursor("EditorTouchState", "ACTION_DOWN: %s tap detected, %s",
+ status, inSameArea);
+ }
+ } else {
+ mMultiTapStatus = MultiTapStatus.FIRST_TAP;
+ mMultiTapInSameArea = false;
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("EditorTouchState", "ACTION_DOWN: first tap detected");
+ }
+ }
+ mLastDownX = event.getX();
+ mLastDownY = event.getY();
+ } else if (action == MotionEvent.ACTION_UP) {
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("EditorTouchState", "ACTION_UP");
+ }
+ mLastUpX = event.getX();
+ mLastUpY = event.getY();
+ mLastUpMillis = event.getEventTime();
+ }
+ }
+}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 90e8ef2..ee169f2 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10860,7 +10860,10 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
if (DEBUG_CURSOR) {
- logCursor("onTouchEvent", MotionEvent.actionToString(event.getActionMasked()));
+ logCursor("onTouchEvent", "%d: %s (%f,%f)",
+ event.getSequenceNumber(),
+ MotionEvent.actionToString(event.getActionMasked()),
+ event.getX(), event.getY());
}
final int action = event.getActionMasked();
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 15b1d75..2f1a15f 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -19,10 +19,10 @@
import com.android.internal.os.BatteryStatsImpl;
import android.bluetooth.BluetoothActivityEnergyInfo;
-import android.net.wifi.WifiActivityEnergyInfo;
import android.os.ParcelFileDescriptor;
import android.os.WorkSource;
import android.os.connectivity.CellularBatteryStats;
+import android.os.connectivity.WifiActivityEnergyInfo;
import android.os.connectivity.WifiBatteryStats;
import android.os.connectivity.GpsBatteryStats;
import android.os.health.HealthStatsParceler;
diff --git a/core/java/com/android/internal/app/procstats/AssociationState.java b/core/java/com/android/internal/app/procstats/AssociationState.java
index 1d4239f..dea3566 100644
--- a/core/java/com/android/internal/app/procstats/AssociationState.java
+++ b/core/java/com/android/internal/app/procstats/AssociationState.java
@@ -945,7 +945,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId, long now) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, long now) {
final long token = proto.start(fieldId);
proto.write(PackageAssociationProcessStatsProto.COMPONENT_NAME, mName);
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java
index 392b8d3..a6bed5b 100644
--- a/core/java/com/android/internal/app/procstats/ProcessState.java
+++ b/core/java/com/android/internal/app/procstats/ProcessState.java
@@ -1341,7 +1341,7 @@
return sb.toString();
}
- public void writeToProto(ProtoOutputStream proto, long fieldId,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId,
String procName, int uid, long now) {
final long token = proto.start(fieldId);
proto.write(ProcessStatsProto.PROCESS, procName);
diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java
index 875cff8..3045410 100644
--- a/core/java/com/android/internal/app/procstats/ProcessStats.java
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.java
@@ -2168,7 +2168,7 @@
/**
* Writes to ProtoOutputStream.
*/
- public void writeToProto(ProtoOutputStream proto, long now, int section) {
+ public void dumpDebug(ProtoOutputStream proto, long now, int section) {
proto.write(ProcessStatsSectionProto.START_REALTIME_MS, mTimePeriodStartRealtime);
proto.write(ProcessStatsSectionProto.END_REALTIME_MS,
mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
@@ -2215,7 +2215,7 @@
for (int iu = 0; iu < uids.size(); iu++) {
final int uid = uids.keyAt(iu);
final ProcessState procState = uids.valueAt(iu);
- procState.writeToProto(proto, ProcessStatsSectionProto.PROCESS_STATS, procName,
+ procState.dumpDebug(proto, ProcessStatsSectionProto.PROCESS_STATS, procName,
uid, now);
}
}
@@ -2230,7 +2230,7 @@
final LongSparseArray<PackageState> vers = uids.valueAt(iu);
for (int iv = 0; iv < vers.size(); iv++) {
final PackageState pkgState = vers.valueAt(iv);
- pkgState.writeToProto(proto, ProcessStatsSectionProto.PACKAGE_STATS, now,
+ pkgState.dumpDebug(proto, ProcessStatsSectionProto.PACKAGE_STATS, now,
section);
}
}
@@ -2283,7 +2283,7 @@
/**
* Writes the containing stats into proto, with options to choose smaller sections.
*/
- public void writeToProto(ProtoOutputStream proto, long fieldId, long now, int section) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, long now, int section) {
final long token = proto.start(fieldId);
proto.write(ProcessStatsPackageProto.PACKAGE, mPackageName);
@@ -2294,7 +2294,7 @@
for (int ip = 0; ip < mProcesses.size(); ip++) {
final String procName = mProcesses.keyAt(ip);
final ProcessState procState = mProcesses.valueAt(ip);
- procState.writeToProto(proto, ProcessStatsPackageProto.PROCESS_STATS, procName,
+ procState.dumpDebug(proto, ProcessStatsPackageProto.PROCESS_STATS, procName,
mUid, now);
}
}
@@ -2302,7 +2302,7 @@
if ((section & ProcessStats.REPORT_PKG_SVC_STATS) != 0) {
for (int is = 0; is < mServices.size(); is++) {
final ServiceState serviceState = mServices.valueAt(is);
- serviceState.writeToProto(proto, ProcessStatsPackageProto.SERVICE_STATS,
+ serviceState.dumpDebug(proto, ProcessStatsPackageProto.SERVICE_STATS,
now);
}
}
@@ -2310,7 +2310,7 @@
if ((section & ProcessStats.REPORT_PKG_ASC_STATS) != 0) {
for (int ia = 0; ia < mAssociations.size(); ia++) {
final AssociationState ascState = mAssociations.valueAt(ia);
- ascState.writeToProto(proto, ProcessStatsPackageProto.ASSOCIATION_STATS,
+ ascState.dumpDebug(proto, ProcessStatsPackageProto.ASSOCIATION_STATS,
now);
}
}
diff --git a/core/java/com/android/internal/app/procstats/ServiceState.java b/core/java/com/android/internal/app/procstats/ServiceState.java
index 72077c4..bf03050 100644
--- a/core/java/com/android/internal/app/procstats/ServiceState.java
+++ b/core/java/com/android/internal/app/procstats/ServiceState.java
@@ -554,7 +554,7 @@
pw.println();
}
- public void writeToProto(ProtoOutputStream proto, long fieldId, long now) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, long now) {
final long token = proto.start(fieldId);
proto.write(PackageServiceStatsProto.SERVICE_NAME, mName);
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
index e48e2df..16628d7 100644
--- a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
+++ b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
@@ -30,6 +30,7 @@
private final @Nullable String mName;
private final int mEnableAfterTargetSdk;
private final boolean mDisabled;
+ private final @Nullable String mDescription;
public long getId() {
return mChangeId;
@@ -48,12 +49,18 @@
return mDisabled;
}
+ public String getDescription() {
+ return mDescription;
+ }
+
public CompatibilityChangeInfo(
- Long changeId, String name, int enableAfterTargetSdk, boolean disabled) {
+ Long changeId, String name, int enableAfterTargetSdk, boolean disabled,
+ String description) {
this.mChangeId = changeId;
this.mName = name;
this.mEnableAfterTargetSdk = enableAfterTargetSdk;
this.mDisabled = disabled;
+ this.mDescription = description;
}
private CompatibilityChangeInfo(Parcel in) {
@@ -61,6 +68,7 @@
mName = in.readString();
mEnableAfterTargetSdk = in.readInt();
mDisabled = in.readBoolean();
+ mDescription = in.readString();
}
@Override
@@ -74,6 +82,7 @@
dest.writeString(mName);
dest.writeInt(mEnableAfterTargetSdk);
dest.writeBoolean(mDisabled);
+ dest.writeString(mDescription);
}
public static final Parcelable.Creator<CompatibilityChangeInfo> CREATOR =
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 25fa65e..bc44fcf 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -33,7 +33,6 @@
import android.net.INetworkStatsService;
import android.net.NetworkStats;
import android.net.Uri;
-import android.net.wifi.WifiActivityEnergyInfo;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.BatteryStats;
@@ -56,6 +55,7 @@
import android.os.WorkSource.WorkChain;
import android.os.connectivity.CellularBatteryStats;
import android.os.connectivity.GpsBatteryStats;
+import android.os.connectivity.WifiActivityEnergyInfo;
import android.os.connectivity.WifiBatteryStats;
import android.provider.Settings;
import android.telephony.CellSignalStrength;
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 8338d78..0faf962 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -506,7 +506,7 @@
/**
* Dump power constants into PowerProfileProto
*/
- public void writeToProto(ProtoOutputStream proto) {
+ public void dumpDebug(ProtoOutputStream proto) {
// cpu.suspend
writePowerConstantToProto(proto, POWER_CPU_SUSPEND, PowerProfileProto.CPU_SUSPEND);
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index b0888f2..121ae1a 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -29,7 +29,7 @@
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
-import android.util.Slog;
+import android.util.Log;
import java.util.Stack;
@@ -841,7 +841,7 @@
msg.replyTo = sm.mMessenger;
synchronized (sm.mHandler.mLockObject) {
if (sm.mHandler.mResultMsg != null) {
- Slog.wtf(TAG, "mResultMsg should be null here");
+ Log.wtf(TAG, "mResultMsg should be null here");
sm.mHandler.mResultMsg = null;
}
dstMessenger.send(msg);
@@ -851,9 +851,9 @@
}
}
} catch (InterruptedException e) {
- Slog.e(TAG, "error in sendMessageSynchronously", e);
+ Log.e(TAG, "error in sendMessageSynchronously", e);
} catch (RemoteException e) {
- Slog.e(TAG, "error in sendMessageSynchronously", e);
+ Log.e(TAG, "error in sendMessageSynchronously", e);
}
sm.recycle();
return resultMsg;
@@ -939,7 +939,7 @@
* @param s
*/
private static void log(String s) {
- Slog.d(TAG, s);
+ Log.d(TAG, s);
}
private final class DeathMonitor implements IBinder.DeathRecipient {
diff --git a/core/java/com/android/internal/util/AsyncService.java b/core/java/com/android/internal/util/AsyncService.java
index e39a2bf..58e4a60 100644
--- a/core/java/com/android/internal/util/AsyncService.java
+++ b/core/java/com/android/internal/util/AsyncService.java
@@ -22,7 +22,7 @@
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
-import android.util.Slog;
+import android.util.Log;
/**
* A service that receives Intents and IBinder transactions
@@ -92,7 +92,7 @@
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- if (DBG) Slog.d(TAG, "onStartCommand");
+ if (DBG) Log.d(TAG, "onStartCommand");
Message msg = mHandler.obtainMessage();
msg.what = CMD_ASYNC_SERVICE_ON_START_INTENT;
@@ -111,7 +111,7 @@
*/
@Override
public void onDestroy() {
- if (DBG) Slog.d(TAG, "onDestroy");
+ if (DBG) Log.d(TAG, "onDestroy");
Message msg = mHandler.obtainMessage();
msg.what = CMD_ASYNC_SERVICE_DESTROY;
diff --git a/core/java/com/android/internal/util/LocalLog.java b/core/java/com/android/internal/util/LocalLog.java
index 8edb739..3916691 100644
--- a/core/java/com/android/internal/util/LocalLog.java
+++ b/core/java/com/android/internal/util/LocalLog.java
@@ -65,7 +65,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
synchronized (mLines) {
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 57bfcac..2ac2975 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -36,6 +36,8 @@
import dalvik.annotation.compat.UnsupportedAppUsage;
+import java.io.IOException;
+
public class BaseIWindow extends IWindow.Stub {
@UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
@@ -101,6 +103,13 @@
@Override
public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
+ if (out != null) {
+ try {
+ out.closeWithError("Unsupported command " + command);
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
}
@Override
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index ce2717b..9f31b59 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -77,12 +77,14 @@
message ActivityDisplayProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
- optional .com.android.server.wm.ConfigurationContainerProto configuration_container = 1;
+ // To be removed soon.
+ optional .com.android.server.wm.ConfigurationContainerProto configuration_container = 1 [deprecated=true];
optional int32 id = 2;
repeated ActivityStackProto stacks = 3;
optional int32 focused_stack_id = 4;
optional .com.android.server.wm.IdentifierProto resumed_activity = 5;
optional bool single_task_instance = 6;
+ optional .com.android.server.wm.DisplayContentProto display = 7;
}
message ActivityStackProto {
diff --git a/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto b/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto
new file mode 100644
index 0000000..138782b
--- /dev/null
+++ b/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+package android.stats.mediaprovider;
+option java_multiple_files = true;
+
+enum VolumeType {
+ // Volume is unknown
+ UNKNOWN = 0;
+ // Volume is MediaStore.VOLUME_INTERNAL
+ INTERNAL = 1;
+ // Volume is MediaStore.VOLUME_EXTERNAL_PRIMARY
+ EXTERNAL_PRIMARY = 2;
+ // Volume is non-primary external storage
+ EXTERNAL_OTHER = 3;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9dc2319..f6e91ef 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5070,6 +5070,10 @@
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
+ <service android:name="com.android.server.usage.UsageStatsIdleService"
+ android:permission="android.permission.BIND_JOB_SERVICE" >
+ </service>
+
<service android:name="com.android.server.net.watchlist.ReportWatchlistJobService"
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 234ffee..38d3e9c 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3750,6 +3750,14 @@
</p>
-->
<attr name="canRequestFingerprintGestures" format="boolean" />
+
+ <!-- Animated image of the accessibility service purpose or behavior, to help users
+ understand how the service can help them.-->
+ <attr name="animatedImageDrawable" format="reference"/>
+ <!-- Html description of the accessibility service, to help users understand
+ how the service can help them.-->
+ <attr name="htmlDescription" format="string"/>
+
<!-- Short description of the accessibility service purpose or behavior.-->
<attr name="description" />
<!-- Brief summary of the accessibility service purpose or behavior. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ffed16e..307d754 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3696,6 +3696,8 @@
instead of 'Emergency calls only' when SIM is unready. -->
<string-array translatable="false" name="config_display_no_service_when_sim_unready">
<item>"DE"</item>
+ <item>"GB"</item>
+ <item>"JP"</item>
</string-array>
<!-- Class names of device specific services inheriting com.android.server.SystemService. The
@@ -4180,4 +4182,10 @@
<string-array name="config_integrityRuleProviderPackages" translatable="false">
<!-- Add packages here -->
</string-array>
+
+ <!-- When true, enables the whitelisted app to handle bug reports from power menu short press. -->
+ <bool name="config_bugReportHandlerEnabled">false</bool>
+
+ <!-- The package name for the default bug report handler app from power menu short press. This app must be whitelisted. -->
+ <string name="config_defaultBugReportHandlerApp" translatable="false"></string>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 57e0e1b..78c4efe 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3002,6 +3002,8 @@
<public name="forceQueryable" />
<!-- @hide @SystemApi -->
<public name="resourcesMap" />
+ <public name="animatedImageDrawable"/>
+ <public name="htmlDescription"/>
</public-group>
<public-group type="drawable" first-id="0x010800b5">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index dcf7379..0f5da39 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1014,23 +1014,29 @@
<string name="permdesc_readContacts" product="tablet">Allows the app to read
data about your contacts stored on your tablet, including the frequency
with which you\'ve called, emailed, or communicated in other ways with
- specific individuals. This permission allows apps to save your contact
+ specific individuals. Apps will also have access to the accounts on your
+ tablet that have created contacts. This may include accounts created by
+ apps you have installed. This permission allows apps to save your contact
data, and malicious apps may share contact data without your
knowledge.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readContacts" product="tv">Allows the app to read
data about your contacts stored on your Android TV device, including the frequency
with which you\'ve called, emailed, or communicated in other ways with
- specific individuals. This permission allows apps to save your contact
- data, and malicious apps may share contact data without your
+ specific individuals. Apps will also have access to the accounts on your
+ Android TV device that have created contacts. This may include accounts
+ created by apps you have installed. This permission allows apps to save
+ your contact data, and malicious apps may share contact data without your
knowledge.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readContacts" product="default">Allows the app to
read data about your contacts stored on your phone, including the
frequency with which you\'ve called, emailed, or communicated in other ways
- with specific individuals. This permission allows apps to save your
- contact data, and malicious apps may share contact data without your
- knowledge.</string>
+ with specific individuals. Apps will also have access to the accounts
+ on your phone that have created contacts. This may include accounts
+ created by apps you have installed. This permission allows apps to
+ save your contact data, and malicious apps may share contact data
+ without your knowledge.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_writeContacts">modify your contacts</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c6c9094..083f33c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3751,6 +3751,10 @@
<java-symbol type="bool" name="config_showBuiltinWirelessChargingAnim" />
+ <!-- For bug report handler -->
+ <java-symbol type="bool" name="config_bugReportHandlerEnabled" />
+ <java-symbol type="string" name="config_defaultBugReportHandlerApp" />
+
<java-symbol type="string" name="usb_device_resolve_prompt_warn" />
<!-- For Accessibility system actions -->
diff --git a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderChangesTest.kt b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderChangesTest.kt
index e01e254..0c3d34e 100644
--- a/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderChangesTest.kt
+++ b/core/tests/ResourceLoaderTests/src/android/content/res/loader/test/ResourceLoaderChangesTest.kt
@@ -31,7 +31,6 @@
import androidx.test.runner.lifecycle.Stage
import com.google.common.truth.Truth.assertThat
import org.junit.After
-import org.junit.Assume
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -43,7 +42,6 @@
import java.util.concurrent.FutureTask
import java.util.concurrent.TimeUnit
-// @Ignore("UiAutomation is crashing with not connected, not sure why")
@RunWith(Parameterized::class)
class ResourceLoaderChangesTest : ResourceLoaderTestBase() {
@@ -75,7 +73,7 @@
@Before
@After
fun disableOverlay() {
-// enableOverlay(OVERLAY_PACKAGE, false)
+ enableOverlay(OVERLAY_PACKAGE, false)
}
@Test
@@ -156,25 +154,32 @@
// All these tests assert for the exact same loaders/values, so extract that logic out
private fun verifySameBeforeAndAfter(block: () -> Resources) {
- // TODO(chiuwinson): atest doesn't work with @Ignore, UiAutomation not connected error
- Assume.assumeFalse(true)
+ fun Resources.resource() = this.getString(android.R.string.cancel)
+ fun Resources.asset() = this.assets.open("Asset.txt").reader().readText()
- val originalValue = resources.getString(android.R.string.cancel)
+ val originalResource = resources.resource()
+ val originalAsset = resources.asset()
- val loader = "stringOne".openLoader()
- addLoader(loader)
+ val loaderResource = "stringOne".openLoader()
+ val loaderAsset = "assetOne".openLoader(dataType = DataType.ASSET)
+ addLoader(loaderResource)
+ addLoader(loaderAsset)
val oldLoaders = resources.loaders
- val oldValue = resources.getString(android.R.string.cancel)
+ val oldResource = resources.resource()
+ val oldAsset = resources.asset()
- assertThat(oldValue).isNotEqualTo(originalValue)
+ assertThat(oldResource).isNotEqualTo(originalResource)
+ assertThat(oldAsset).isNotEqualTo(originalAsset)
val newResources = block()
val newLoaders = newResources.loaders
- val newValue = newResources.getString(android.R.string.cancel)
+ val newResource = newResources.resource()
+ val newAsset = newResources.asset()
- assertThat(newValue).isEqualTo(oldValue)
+ assertThat(newResource).isEqualTo(oldResource)
+ assertThat(newAsset).isEqualTo(oldAsset)
assertThat(newLoaders).isEqualTo(oldLoaders)
}
diff --git a/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java
new file mode 100644
index 0000000..de6f8f7
--- /dev/null
+++ b/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 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 android.app.timedetector;
+
+import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
+import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.util.TimestampedValue;
+
+import org.junit.Test;
+
+public class ManualTimeSuggestionTest {
+
+ private static final TimestampedValue<Long> ARBITRARY_TIME =
+ new TimestampedValue<>(1111L, 2222L);
+
+ @Test
+ public void testEquals() {
+ ManualTimeSuggestion one = new ManualTimeSuggestion(ARBITRARY_TIME);
+ assertEquals(one, one);
+
+ ManualTimeSuggestion two = new ManualTimeSuggestion(ARBITRARY_TIME);
+ assertEquals(one, two);
+ assertEquals(two, one);
+
+ TimestampedValue<Long> differentTime = new TimestampedValue<>(
+ ARBITRARY_TIME.getReferenceTimeMillis() + 1,
+ ARBITRARY_TIME.getValue());
+ ManualTimeSuggestion three = new ManualTimeSuggestion(differentTime);
+ assertNotEquals(one, three);
+ assertNotEquals(three, one);
+
+ // DebugInfo must not be considered in equals().
+ one.addDebugInfo("Debug info 1");
+ two.addDebugInfo("Debug info 2");
+ assertEquals(one, two);
+ }
+
+ @Test
+ public void testParcelable() {
+ ManualTimeSuggestion suggestion = new ManualTimeSuggestion(ARBITRARY_TIME);
+ assertRoundTripParcelable(suggestion);
+
+ // DebugInfo should also be stored (but is not checked by equals()
+ suggestion.addDebugInfo("This is debug info");
+ ManualTimeSuggestion rtSuggestion = roundTripParcelable(suggestion);
+ assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
+ }
+}
diff --git a/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java
index c9a86dc..bee270e 100644
--- a/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java
+++ b/core/tests/coretests/src/android/app/timedetector/PhoneTimeSuggestionTest.java
@@ -16,11 +16,12 @@
package android.app.timedetector;
+import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
+import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-import android.os.Parcel;
-import android.os.Parcelable;
import android.util.TimestampedValue;
import org.junit.Test;
@@ -30,53 +31,67 @@
@Test
public void testEquals() {
- PhoneTimeSuggestion one = new PhoneTimeSuggestion(PHONE_ID);
- assertEquals(one, one);
+ PhoneTimeSuggestion.Builder builder1 = new PhoneTimeSuggestion.Builder(PHONE_ID);
+ {
+ PhoneTimeSuggestion one = builder1.build();
+ assertEquals(one, one);
+ }
- PhoneTimeSuggestion two = new PhoneTimeSuggestion(PHONE_ID);
- assertEquals(one, two);
- assertEquals(two, one);
+ PhoneTimeSuggestion.Builder builder2 = new PhoneTimeSuggestion.Builder(PHONE_ID);
+ {
+ PhoneTimeSuggestion one = builder1.build();
+ PhoneTimeSuggestion two = builder2.build();
+ assertEquals(one, two);
+ assertEquals(two, one);
+ }
- one.setUtcTime(new TimestampedValue<>(1111L, 2222L));
- assertEquals(one, one);
+ builder1.setUtcTime(new TimestampedValue<>(1111L, 2222L));
+ {
+ PhoneTimeSuggestion one = builder1.build();
+ assertEquals(one, one);
+ }
- two.setUtcTime(new TimestampedValue<>(1111L, 2222L));
- assertEquals(one, two);
- assertEquals(two, one);
+ builder2.setUtcTime(new TimestampedValue<>(1111L, 2222L));
+ {
+ PhoneTimeSuggestion one = builder1.build();
+ PhoneTimeSuggestion two = builder2.build();
+ assertEquals(one, two);
+ assertEquals(two, one);
+ }
- PhoneTimeSuggestion three = new PhoneTimeSuggestion(PHONE_ID + 1);
- three.setUtcTime(new TimestampedValue<>(1111L, 2222L));
- assertNotEquals(one, three);
- assertNotEquals(three, one);
+ PhoneTimeSuggestion.Builder builder3 = new PhoneTimeSuggestion.Builder(PHONE_ID + 1);
+ builder3.setUtcTime(new TimestampedValue<>(1111L, 2222L));
+ {
+ PhoneTimeSuggestion one = builder1.build();
+ PhoneTimeSuggestion three = builder3.build();
+ assertNotEquals(one, three);
+ assertNotEquals(three, one);
+ }
// DebugInfo must not be considered in equals().
- one.addDebugInfo("Debug info 1");
- two.addDebugInfo("Debug info 2");
- assertEquals(one, two);
+ builder1.addDebugInfo("Debug info 1");
+ builder2.addDebugInfo("Debug info 2");
+ {
+ PhoneTimeSuggestion one = builder1.build();
+ PhoneTimeSuggestion two = builder2.build();
+ assertEquals(one, two);
+ }
}
@Test
public void testParcelable() {
- PhoneTimeSuggestion one = new PhoneTimeSuggestion(PHONE_ID);
- assertEquals(one, roundTripParcelable(one));
+ PhoneTimeSuggestion.Builder builder = new PhoneTimeSuggestion.Builder(PHONE_ID);
+ assertRoundTripParcelable(builder.build());
- one.setUtcTime(new TimestampedValue<>(1111L, 2222L));
- assertEquals(one, roundTripParcelable(one));
+ builder.setUtcTime(new TimestampedValue<>(1111L, 2222L));
+ assertRoundTripParcelable(builder.build());
// DebugInfo should also be stored (but is not checked by equals()
- one.addDebugInfo("This is debug info");
- PhoneTimeSuggestion two = roundTripParcelable(one);
- assertEquals(one.getDebugInfo(), two.getDebugInfo());
- }
-
- @SuppressWarnings("unchecked")
- private static <T extends Parcelable> T roundTripParcelable(T one) {
- Parcel parcel = Parcel.obtain();
- parcel.writeTypedObject(one, 0);
- parcel.setDataPosition(0);
-
- T toReturn = (T) parcel.readTypedObject(PhoneTimeSuggestion.CREATOR);
- parcel.recycle();
- return toReturn;
+ {
+ PhoneTimeSuggestion suggestion1 = builder.build();
+ builder.addDebugInfo("This is debug info");
+ PhoneTimeSuggestion rtSuggestion1 = roundTripParcelable(suggestion1);
+ assertEquals(suggestion1.getDebugInfo(), rtSuggestion1.getDebugInfo());
+ }
}
}
diff --git a/core/tests/coretests/src/android/content/res/ConfigurationTest.java b/core/tests/coretests/src/android/content/res/ConfigurationTest.java
index c231e61..2c956c9 100644
--- a/core/tests/coretests/src/android/content/res/ConfigurationTest.java
+++ b/core/tests/coretests/src/android/content/res/ConfigurationTest.java
@@ -96,7 +96,7 @@
.setExtension('u', "nu-latn").build();
Configuration write = new Configuration();
write.setLocales(new LocaleList(arabic, urdu, urduExtension));
- writeToProto(proto, write);
+ dumpDebug(proto, write);
assertTrue("Failed to write configs to proto.", proto.exists());
final Configuration read = new Configuration();
@@ -148,13 +148,13 @@
assertEquals(SMALLEST_SCREEN_WIDTH_DP_UNDEFINED, config.smallestScreenWidthDp);
}
- private void writeToProto(File f, Configuration config) throws Exception {
+ private void dumpDebug(File f, Configuration config) throws Exception {
final AtomicFile af = new AtomicFile(f);
FileOutputStream fos = af.startWrite();
try {
final ProtoOutputStream protoOut = new ProtoOutputStream(fos);
final long token = protoOut.start(IntervalStatsProto.CONFIGURATIONS);
- config.writeToProto(protoOut, IntervalStatsProto.Configuration.CONFIG, false, false);
+ config.dumpDebug(protoOut, IntervalStatsProto.Configuration.CONFIG, false, false);
protoOut.end(token);
protoOut.flush();
af.finishWrite(fos);
diff --git a/core/tests/coretests/src/android/service/controls/ControlActionTest.java b/core/tests/coretests/src/android/service/controls/ControlActionTest.java
new file mode 100644
index 0000000..ef4912f
--- /dev/null
+++ b/core/tests/coretests/src/android/service/controls/ControlActionTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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 android.service.controls;
+
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ControlActionTest {
+
+ private static final String TEST_ID = "TEST_ID";
+
+ @Test
+ public void testUnparcelingCorrectClass_boolean() {
+ ControlAction toParcel = new BooleanAction(TEST_ID, true);
+
+ ControlAction fromParcel = parcelAndUnparcel(toParcel);
+
+ assertEquals(ControlAction.TYPE_BOOLEAN, fromParcel.getActionType());
+ assertTrue(fromParcel instanceof BooleanAction);
+ }
+
+ @Test
+ public void testUnparcelingCorrectClass_float() {
+ ControlAction toParcel = new FloatAction(TEST_ID, 1);
+
+ ControlAction fromParcel = parcelAndUnparcel(toParcel);
+
+ assertEquals(ControlAction.TYPE_FLOAT, fromParcel.getActionType());
+ assertTrue(fromParcel instanceof FloatAction);
+ }
+
+ private ControlAction parcelAndUnparcel(ControlAction toParcel) {
+ Parcel parcel = Parcel.obtain();
+
+ assertNotNull(parcel);
+
+ parcel.setDataPosition(0);
+ toParcel.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ return ControlAction.CREATOR.createFromParcel(parcel);
+ }
+}
diff --git a/core/tests/coretests/src/android/service/controls/ControlTemplateTest.java b/core/tests/coretests/src/android/service/controls/ControlTemplateTest.java
new file mode 100644
index 0000000..4fa4e1d
--- /dev/null
+++ b/core/tests/coretests/src/android/service/controls/ControlTemplateTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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 android.service.controls;
+
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.annotation.DrawableRes;
+import android.graphics.drawable.Icon;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+import java.security.InvalidParameterException;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ControlTemplateTest {
+
+ private static final String PACKAGE_NAME = "com.android.frameworks.coretests";
+ private static final @DrawableRes int TEST_ICON_ID = R.drawable.box;
+ private static final String TEST_ID = "TEST_ID";
+ private static final CharSequence TEST_CONTENT_DESCRIPTION = "TEST_CONTENT_DESCRIPTION";
+ private Icon mIcon;
+ private ControlButton mControlButton;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mIcon = Icon.createWithResource(PACKAGE_NAME, TEST_ICON_ID);
+ mControlButton = new ControlButton(true, mIcon, TEST_CONTENT_DESCRIPTION);
+ }
+
+ @Test
+ public void testUnparcelingCorrectClass_none() {
+ ControlTemplate toParcel = ControlTemplate.NO_TEMPLATE;
+
+ ControlTemplate fromParcel = parcelAndUnparcel(toParcel);
+
+ assertEquals(ControlTemplate.NO_TEMPLATE, fromParcel);
+ }
+
+ @Test
+ public void testUnparcelingCorrectClass_toggle() {
+ ControlTemplate toParcel = new ToggleTemplate(TEST_ID, mControlButton);
+
+ ControlTemplate fromParcel = parcelAndUnparcel(toParcel);
+
+ assertEquals(ControlTemplate.TYPE_TOGGLE, fromParcel.getTemplateType());
+ assertTrue(fromParcel instanceof ToggleTemplate);
+ }
+
+ @Test
+ public void testUnparcelingCorrectClass_range() {
+ ControlTemplate toParcel = new RangeTemplate(TEST_ID, 0, 2, 1, 1, "%f");
+
+ ControlTemplate fromParcel = parcelAndUnparcel(toParcel);
+
+ assertEquals(ControlTemplate.TYPE_RANGE, fromParcel.getTemplateType());
+ assertTrue(fromParcel instanceof RangeTemplate);
+ }
+
+ @Test(expected = InvalidParameterException.class)
+ public void testRangeParameters_minMax() {
+ RangeTemplate range = new RangeTemplate(TEST_ID, 2, 0, 1, 1, "%f");
+ }
+
+ @Test(expected = InvalidParameterException.class)
+ public void testRangeParameters_minCurrent() {
+ RangeTemplate range = new RangeTemplate(TEST_ID, 0, 2, -1, 1, "%f");
+ }
+
+ @Test(expected = InvalidParameterException.class)
+ public void testRangeParameters_maxCurrent() {
+ RangeTemplate range = new RangeTemplate(TEST_ID, 0, 2, 3, 1, "%f");
+ }
+
+ @Test(expected = InvalidParameterException.class)
+ public void testRangeParameters_negativeStep() {
+ RangeTemplate range = new RangeTemplate(TEST_ID, 0, 2, 1, -1, "%f");
+ }
+
+ @Test
+ public void testUnparcelingCorrectClass_thumbnail() {
+ ControlTemplate toParcel = new ThumbnailTemplate(TEST_ID, mIcon, TEST_CONTENT_DESCRIPTION);
+
+ ControlTemplate fromParcel = parcelAndUnparcel(toParcel);
+
+ assertEquals(ControlTemplate.TYPE_THUMBNAIL, fromParcel.getTemplateType());
+ assertTrue(fromParcel instanceof ThumbnailTemplate);
+ }
+
+ @Test
+ public void testUnparcelingCorrectClass_discreteToggle() {
+ ControlTemplate toParcel =
+ new DiscreteToggleTemplate(TEST_ID, mControlButton, mControlButton);
+
+ ControlTemplate fromParcel = parcelAndUnparcel(toParcel);
+
+ assertEquals(ControlTemplate.TYPE_DISCRETE_TOGGLE, fromParcel.getTemplateType());
+ assertTrue(fromParcel instanceof DiscreteToggleTemplate);
+ }
+
+ private ControlTemplate parcelAndUnparcel(ControlTemplate toParcel) {
+ Parcel parcel = Parcel.obtain();
+
+ assertNotNull(parcel);
+
+ parcel.setDataPosition(0);
+ toParcel.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ return ControlTemplate.CREATOR.createFromParcel(parcel);
+ }
+}
diff --git a/core/tests/coretests/src/android/util/StatsEventTest.java b/core/tests/coretests/src/android/util/StatsEventTest.java
index 93f11db..097bada 100644
--- a/core/tests/coretests/src/android/util/StatsEventTest.java
+++ b/core/tests/coretests/src/android/util/StatsEventTest.java
@@ -53,8 +53,8 @@
final ByteBuffer buffer =
ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
- assertWithMessage("Root element in buffer is not TYPE_ERRORS")
- .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ERRORS);
+ assertWithMessage("Root element in buffer is not TYPE_OBJECT")
+ .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
assertWithMessage("Incorrect number of elements in root object")
.that(buffer.get()).isEqualTo(3);
@@ -71,6 +71,9 @@
assertWithMessage("Incorrect atom id")
.that(buffer.getInt()).isEqualTo(expectedAtomId);
+ assertWithMessage("Third element is not errors type")
+ .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ERRORS);
+
final int errorMask = buffer.getInt();
assertWithMessage("ERROR_NO_ATOM_ID should be the only error in the error mask")
diff --git a/core/tests/coretests/src/android/widget/EditorTouchStateTest.java b/core/tests/coretests/src/android/widget/EditorTouchStateTest.java
new file mode 100644
index 0000000..6d50e3a
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/EditorTouchStateTest.java
@@ -0,0 +1,229 @@
+/*
+ * 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 android.widget;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+import android.widget.EditorTouchState.MultiTapStatus;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+@SmallTest
+public class EditorTouchStateTest {
+
+ private EditorTouchState mTouchState;
+ private ViewConfiguration mConfig;
+
+ @Before
+ public void before() throws Exception {
+ mTouchState = new EditorTouchState();
+ mConfig = new ViewConfiguration();
+ }
+
+ @Test
+ public void testUpdate_singleTap() throws Exception {
+ // Simulate an ACTION_DOWN event.
+ long event1Time = 1000;
+ MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
+ mTouchState.update(event1, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 0, 0);
+
+ // Simulate an ACTION_UP event.
+ long event2Time = 1001;
+ MotionEvent event2 = upEvent(event1Time, event2Time, 20f, 30f);
+ mTouchState.update(event2, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 20f, 30f);
+
+ // Generate an ACTION_DOWN event whose time is after the double-tap timeout.
+ long event3Time = event2Time + ViewConfiguration.getDoubleTapTimeout() + 1;
+ MotionEvent event3 = downEvent(event3Time, event3Time, 22f, 33f);
+ mTouchState.update(event3, mConfig);
+ assertSingleTap(mTouchState, 22f, 33f, 20f, 30f);
+ }
+
+ @Test
+ public void testUpdate_doubleTap_sameArea() throws Exception {
+ // Simulate an ACTION_DOWN event.
+ long event1Time = 1000;
+ MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
+ mTouchState.update(event1, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 0, 0);
+
+ // Simulate an ACTION_UP event.
+ long event2Time = 1001;
+ MotionEvent event2 = upEvent(event1Time, event2Time, 20f, 30f);
+ mTouchState.update(event2, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 20f, 30f);
+
+ // Generate an ACTION_DOWN event whose time is within the double-tap timeout.
+ long event3Time = 1002;
+ MotionEvent event3 = downEvent(event3Time, event3Time, 22f, 33f);
+ mTouchState.update(event3, mConfig);
+ assertTap(mTouchState, 22f, 33f, 20f, 30f,
+ MultiTapStatus.DOUBLE_TAP, true);
+ }
+
+ @Test
+ public void testUpdate_doubleTap_notSameArea() throws Exception {
+ // Simulate an ACTION_DOWN event.
+ long event1Time = 1000;
+ MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
+ mTouchState.update(event1, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 0, 0);
+
+ // Simulate an ACTION_UP event.
+ long event2Time = 1001;
+ MotionEvent event2 = upEvent(event1Time, event2Time, 20f, 30f);
+ mTouchState.update(event2, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 20f, 30f);
+
+ // Generate an ACTION_DOWN event whose time is within the double-tap timeout.
+ long event3Time = 1002;
+ MotionEvent event3 = downEvent(event3Time, event3Time, 200f, 300f);
+ mTouchState.update(event3, mConfig);
+ assertTap(mTouchState, 200f, 300f, 20f, 30f,
+ MultiTapStatus.DOUBLE_TAP, false);
+
+ // Simulate an ACTION_UP event.
+ long event4Time = 1003;
+ MotionEvent event4 = upEvent(event3Time, event4Time, 200f, 300f);
+ mTouchState.update(event4, mConfig);
+ assertTap(mTouchState, 200f, 300f, 200f, 300f,
+ MultiTapStatus.DOUBLE_TAP, false);
+ }
+
+ @Test
+ public void testUpdate_tripleClick_mouse() throws Exception {
+ // Simulate an ACTION_DOWN event.
+ long event1Time = 1000;
+ MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
+ event1.setSource(InputDevice.SOURCE_MOUSE);
+ mTouchState.update(event1, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 0, 0);
+
+ // Simulate an ACTION_UP event.
+ long event2Time = 1001;
+ MotionEvent event2 = upEvent(event1Time, event2Time, 20f, 30f);
+ event2.setSource(InputDevice.SOURCE_MOUSE);
+ mTouchState.update(event2, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 20f, 30f);
+
+ // Generate a second ACTION_DOWN event whose time is within the double-tap timeout.
+ long event3Time = 1002;
+ MotionEvent event3 = downEvent(event3Time, event3Time, 21f, 31f);
+ event3.setSource(InputDevice.SOURCE_MOUSE);
+ mTouchState.update(event3, mConfig);
+ assertTap(mTouchState, 21f, 31f, 20f, 30f,
+ MultiTapStatus.DOUBLE_TAP, true);
+
+ // Simulate an ACTION_UP event.
+ long event4Time = 1003;
+ MotionEvent event4 = upEvent(event3Time, event4Time, 21f, 31f);
+ event4.setSource(InputDevice.SOURCE_MOUSE);
+ mTouchState.update(event4, mConfig);
+ assertTap(mTouchState, 21f, 31f, 21f, 31f,
+ MultiTapStatus.DOUBLE_TAP, true);
+
+ // Generate a third ACTION_DOWN event whose time is within the double-tap timeout.
+ long event5Time = 1004;
+ MotionEvent event5 = downEvent(event5Time, event5Time, 22f, 32f);
+ event5.setSource(InputDevice.SOURCE_MOUSE);
+ mTouchState.update(event5, mConfig);
+ assertTap(mTouchState, 22f, 32f, 21f, 31f,
+ MultiTapStatus.TRIPLE_CLICK, true);
+ }
+
+ @Test
+ public void testUpdate_tripleClick_touch() throws Exception {
+ // Simulate an ACTION_DOWN event.
+ long event1Time = 1000;
+ MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
+ mTouchState.update(event1, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 0, 0);
+
+ // Simulate an ACTION_UP event.
+ long event2Time = 1001;
+ MotionEvent event2 = upEvent(event1Time, event2Time, 20f, 30f);
+ mTouchState.update(event2, mConfig);
+ assertSingleTap(mTouchState, 20f, 30f, 20f, 30f);
+
+ // Generate a second ACTION_DOWN event whose time is within the double-tap timeout.
+ long event3Time = 1002;
+ MotionEvent event3 = downEvent(event3Time, event3Time, 21f, 31f);
+ mTouchState.update(event3, mConfig);
+ assertTap(mTouchState, 21f, 31f, 20f, 30f,
+ MultiTapStatus.DOUBLE_TAP, true);
+
+ // Simulate an ACTION_UP event.
+ long event4Time = 1003;
+ MotionEvent event4 = upEvent(event3Time, event4Time, 21f, 31f);
+ mTouchState.update(event4, mConfig);
+ assertTap(mTouchState, 21f, 31f, 21f, 31f,
+ MultiTapStatus.DOUBLE_TAP, true);
+
+ // Generate a third ACTION_DOWN event whose time is within the double-tap timeout.
+ long event5Time = 1004;
+ MotionEvent event5 = downEvent(event5Time, event5Time, 22f, 32f);
+ mTouchState.update(event5, mConfig);
+ assertTap(mTouchState, 22f, 32f, 21f, 31f,
+ MultiTapStatus.FIRST_TAP, false);
+ }
+
+ private static MotionEvent downEvent(long downTime, long eventTime, float x, float y) {
+ return MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0);
+ }
+
+ private static MotionEvent upEvent(long downTime, long eventTime, float x, float y) {
+ return MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
+ }
+
+ private static void assertSingleTap(EditorTouchState touchState, float lastDownX,
+ float lastDownY, float lastUpX, float lastUpY) {
+ assertThat(touchState.getLastDownX(), is(lastDownX));
+ assertThat(touchState.getLastDownY(), is(lastDownY));
+ assertThat(touchState.getLastUpX(), is(lastUpX));
+ assertThat(touchState.getLastUpY(), is(lastUpY));
+ assertThat(touchState.isDoubleTap(), is(false));
+ assertThat(touchState.isTripleClick(), is(false));
+ assertThat(touchState.isMultiTap(), is(false));
+ assertThat(touchState.isMultiTapInSameArea(), is(false));
+ }
+
+ private static void assertTap(EditorTouchState touchState,
+ float lastDownX, float lastDownY, float lastUpX, float lastUpY,
+ @MultiTapStatus int multiTapStatus, boolean isMultiTapInSameArea) {
+ assertThat(touchState.getLastDownX(), is(lastDownX));
+ assertThat(touchState.getLastDownY(), is(lastDownY));
+ assertThat(touchState.getLastUpX(), is(lastUpX));
+ assertThat(touchState.getLastUpY(), is(lastUpY));
+ assertThat(touchState.isDoubleTap(), is(multiTapStatus == MultiTapStatus.DOUBLE_TAP));
+ assertThat(touchState.isTripleClick(), is(multiTapStatus == MultiTapStatus.TRIPLE_CLICK));
+ assertThat(touchState.isMultiTap(), is(multiTapStatus == MultiTapStatus.DOUBLE_TAP
+ || multiTapStatus == MultiTapStatus.TRIPLE_CLICK));
+ assertThat(touchState.isMultiTapInSameArea(), is(isMultiTapInSameArea));
+ }
+}
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index c49d663..ff521be 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -104,7 +104,7 @@
prebuilt_etc {
name: "privapp_whitelist_com.android.settings",
- product_specific: true,
+ system_ext_specific: true,
sub_dir: "permissions",
src: "com.android.settings.xml",
filename_from_src: true,
diff --git a/data/etc/CleanSpec.mk b/data/etc/CleanSpec.mk
index cffb1ba..3fe421e 100644
--- a/data/etc/CleanSpec.mk
+++ b/data/etc/CleanSpec.mk
@@ -49,6 +49,8 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.emergency.xml)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.provision.xml)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.provision.xml)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.settings.xml)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.settings.xml)
# ******************************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
# ******************************************************************
diff --git a/graphics/java/android/graphics/Point.java b/graphics/java/android/graphics/Point.java
index 3614f3b..9f71a0f 100644
--- a/graphics/java/android/graphics/Point.java
+++ b/graphics/java/android/graphics/Point.java
@@ -132,7 +132,7 @@
* @param fieldId Field Id of the Rect as defined in the parent message
* @hide
*/
- public void writeToProto(@NonNull ProtoOutputStream protoOutputStream, long fieldId) {
+ public void dumpDebug(@NonNull ProtoOutputStream protoOutputStream, long fieldId) {
final long token = protoOutputStream.start(fieldId);
protoOutputStream.write(PointProto.X, x);
protoOutputStream.write(PointProto.Y, y);
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index d47f682..9e1946c 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -239,7 +239,7 @@
* @param fieldId Field Id of the Rect as defined in the parent message
* @hide
*/
- public void writeToProto(@NonNull ProtoOutputStream protoOutputStream, long fieldId) {
+ public void dumpDebug(@NonNull ProtoOutputStream protoOutputStream, long fieldId) {
final long token = protoOutputStream.start(fieldId);
protoOutputStream.write(RectProto.LEFT, left);
protoOutputStream.write(RectProto.TOP, top);
diff --git a/media/Android.bp b/media/Android.bp
index 022fa9b..1912930 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -45,8 +45,8 @@
filegroup {
name: "updatable-media-srcs",
srcs: [
- ":mediasession2-srcs",
":mediaparser-srcs",
+ ":mediasession2-srcs",
],
}
@@ -73,7 +73,8 @@
name: "mediaparser-srcs",
srcs: [
"apex/java/android/media/MediaParser.java"
- ]
+ ],
+ path: "apex/java"
}
metalava_updatable_media_args = " --error UnhiddenSystemApi " +
diff --git a/media/apex/java/android/media/MediaParser.java b/media/apex/java/android/media/MediaParser.java
index c06e283..8824269 100644
--- a/media/apex/java/android/media/MediaParser.java
+++ b/media/apex/java/android/media/MediaParser.java
@@ -15,10 +15,47 @@
*/
package android.media;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.Uri;
+import android.text.TextUtils;
import android.util.Pair;
+import android.util.SparseArray;
+import com.google.android.exoplayer2.C;
+import com.google.android.exoplayer2.Format;
+import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
+import com.google.android.exoplayer2.extractor.Extractor;
+import com.google.android.exoplayer2.extractor.ExtractorInput;
+import com.google.android.exoplayer2.extractor.ExtractorOutput;
+import com.google.android.exoplayer2.extractor.PositionHolder;
+import com.google.android.exoplayer2.extractor.SeekMap.SeekPoints;
+import com.google.android.exoplayer2.extractor.TrackOutput;
+import com.google.android.exoplayer2.extractor.amr.AmrExtractor;
+import com.google.android.exoplayer2.extractor.flv.FlvExtractor;
+import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
+import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor;
+import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
+import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
+import com.google.android.exoplayer2.extractor.ogg.OggExtractor;
+import com.google.android.exoplayer2.extractor.ts.Ac3Extractor;
+import com.google.android.exoplayer2.extractor.ts.Ac4Extractor;
+import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
+import com.google.android.exoplayer2.extractor.ts.PsExtractor;
+import com.google.android.exoplayer2.extractor.ts.TsExtractor;
+import com.google.android.exoplayer2.extractor.wav.WavExtractor;
+import com.google.android.exoplayer2.upstream.DataSource;
+import com.google.android.exoplayer2.upstream.DataSpec;
+import com.google.android.exoplayer2.upstream.TransferListener;
+import com.google.android.exoplayer2.util.ParsableByteArray;
+
+import java.io.EOFException;
import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
/**
* Parses media container formats and extracts contained media samples and metadata.
@@ -32,16 +69,93 @@
* <p>Users must implement the following to use this class.
*
* <ul>
- * <li>{@link Input}: Provides the media containers bytes to parse.
- * <li>{@link OutputCallback}: Provides a sink for all extracted data and metadata.
+ * <li>{@link InputReader}: Provides the media container's bytes to parse.
+ * <li>{@link OutputConsumer}: Provides a sink for all extracted data and metadata.
* </ul>
*
- * TODO: Add usage example here.
+ * <p>The following code snippet includes a usage example:
+ *
+ * <pre>
+ * MyOutputConsumer myOutputConsumer = new MyOutputConsumer();
+ * MyInputReader myInputReader = new MyInputReader("www.example.com");
+ * MediaParser mediaParser = MediaParser.create(myOutputConsumer);
+ *
+ * while (mediaParser.advance(myInputReader)) {}
+ *
+ * mediaParser.release();
+ * mediaParser = null;
+ * </pre>
+ *
+ * <p>The following code snippet provides a rudimentary {@link OutputConsumer} sample implementation
+ * which extracts and publishes all video samples:
+ *
+ * <pre>
+ *
+ * class VideoOutputConsumer implements MediaParser.OutputConsumer {
+ *
+ * private static final int MAXIMUM_SAMPLE_SIZE = ...;
+ * private byte[] sampleDataBuffer = new byte[MAXIMUM_SAMPLE_SIZE];
+ * private int videoTrackIndex = -1;
+ * private int bytesWrittenCount = 0;
+ *
+ * \@Override
+ * public void onSeekMap(int i, @NonNull MediaFormat mediaFormat) { \/* Do nothing. *\/ }
+ *
+ * \@Override
+ * public void onFormat(int i, @NonNull MediaFormat mediaFormat) {
+ * if (videoTrackIndex == -1 && mediaFormat
+ * .getString(MediaFormat.KEY_MIME, \/* defaultValue= *\/ "").startsWith("video/")) {
+ * videoTrackIndex = i;
+ * }
+ * }
+ *
+ * \@Override
+ * public void onSampleData(int trackIndex, @NonNull InputReader inputReader)
+ * throws IOException, InterruptedException {
+ * int numberOfBytesToRead = (int) inputReader.getLength();
+ * if (videoTrackIndex != trackIndex) {
+ * // Discard contents.
+ * inputReader.read(\/* bytes= *\/ null, \/* offset= *\/ 0, numberOfBytesToRead);
+ * }
+ * int bytesRead = inputReader.read(sampleDataBuffer, bytesWrittenCount, numberOfBytesToRead);
+ * bytesWrittenCount += bytesRead;
+ * }
+ *
+ * \@Override
+ * public void onSampleCompleted(
+ * int trackIndex,
+ * long timeUs,
+ * int flags,
+ * int size,
+ * int offset,
+ * \@Nullable CryptoInfo cryptoData) {
+ * if (videoTrackIndex != trackIndex) {
+ * return; // It's not the video track. Ignore.
+ * }
+ * byte[] sampleData = new byte[size];
+ * System.arraycopy(sampleDataBuffer, bytesWrittenCount - size - offset, sampleData, \/*
+ * destPos= *\/ 0, size);
+ * // Place trailing bytes at the start of the buffer.
+ * System.arraycopy(
+ * sampleDataBuffer,
+ * bytesWrittenCount - offset,
+ * sampleDataBuffer,
+ * \/* destPos= *\/ 0,
+ * \/* size= *\/ offset);
+ * publishSample(sampleData, timeUs, flags);
+ * }
+ * }
+ *
+ * </pre>
*/
-// @HiddenApi
public final class MediaParser {
- /** Maps seek positions to corresponding positions in the stream. */
+ /**
+ * Maps seek positions to {@link SeekPoint SeekPoints} in the stream.
+ *
+ * <p>A {@link SeekPoint} is a position in the stream from which a player may successfully start
+ * playing media samples.
+ */
public interface SeekMap {
/** Returned by {@link #getDurationUs()} when the duration is unknown. */
@@ -62,13 +176,14 @@
* <p>{@code getSeekPoints(timeUs).first} contains the latest seek point for samples with
* timestamp equal to or smaller than {@code timeUs}.
*
- * <p>{@code getSeekPoints(timeUs).second} contains the earlies seek point for samples with
+ * <p>{@code getSeekPoints(timeUs).second} contains the earliest seek point for samples with
* timestamp equal to or greater than {@code timeUs}. If a seek point exists for {@code
* timeUs}, the returned pair will contain the same {@link SeekPoint} twice.
*
* @param timeUs A seek time in microseconds.
* @return The corresponding {@link SeekPoint SeekPoints}.
*/
+ @NonNull
Pair<SeekPoint, SeekPoint> getSeekPoints(long timeUs);
}
@@ -76,30 +191,30 @@
public static final class SeekPoint {
/** A {@link SeekPoint} whose time and byte offset are both set to 0. */
- public static final SeekPoint START = new SeekPoint(0, 0);
+ public static final @NonNull SeekPoint START = new SeekPoint(0, 0);
/** The time of the seek point, in microseconds. */
- public final long mTimeUs;
+ public final long timeUs;
/** The byte offset of the seek point. */
- public final long mPosition;
+ public final long position;
/**
* @param timeUs The time of the seek point, in microseconds.
* @param position The byte offset of the seek point.
*/
- public SeekPoint(long timeUs, long position) {
- this.mTimeUs = timeUs;
- this.mPosition = position;
+ private SeekPoint(long timeUs, long position) {
+ this.timeUs = timeUs;
+ this.position = position;
}
@Override
- public String toString() {
- return "[timeUs=" + mTimeUs + ", position=" + mPosition + "]";
+ public @NonNull String toString() {
+ return "[timeUs=" + timeUs + ", position=" + position + "]";
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -107,25 +222,26 @@
return false;
}
SeekPoint other = (SeekPoint) obj;
- return mTimeUs == other.mTimeUs && mPosition == other.mPosition;
+ return timeUs == other.timeUs && position == other.position;
}
@Override
public int hashCode() {
- int result = (int) mTimeUs;
- result = 31 * result + (int) mPosition;
+ int result = (int) timeUs;
+ result = 31 * result + (int) position;
return result;
}
}
/** Provides input data to {@link MediaParser}. */
- public interface Input {
+ public interface InputReader {
/**
* Reads up to {@code readLength} bytes of data and stores them into {@code buffer},
* starting at index {@code offset}.
*
- * <p>The call will block until at least one byte of data has been read.
+ * <p>This method blocks until at least one byte is read, the end of input is detected, or
+ * an exception is thrown. The read position advances to the first unread byte.
*
* @param buffer The buffer into which the read data should be stored.
* @param offset The start offset into {@code buffer} at which data should be written.
@@ -134,7 +250,7 @@
* of the input has been reached.
* @throws java.io.IOException If an error occurs reading from the source.
*/
- int read(byte[] buffer, int offset, int readLength)
+ int read(@NonNull byte[] buffer, int offset, int readLength)
throws IOException, InterruptedException;
/** Returns the current read position (byte offset) in the stream. */
@@ -144,22 +260,39 @@
long getLength();
}
- /** Receives extracted media sample data and metadata from {@link MediaParser}. */
- public interface OutputCallback {
+ /** {@link InputReader} that allows setting the read position. */
+ public interface SeekableInputReader extends InputReader {
/**
- * Called when the number of tracks is defined.
+ * Sets the read position at the given {@code position}.
*
- * @param numberOfTracks The number of tracks in the stream.
+ * <p>{@link #advance} will immediately return after calling this method.
+ *
+ * @param position The position to seek to, in bytes.
*/
- void onTracksFound(int numberOfTracks);
+ void seekToPosition(long position);
+ }
+
+ /** Receives extracted media sample data and metadata from {@link MediaParser}. */
+ public interface OutputConsumer {
/**
* Called when a {@link SeekMap} has been extracted from the stream.
*
+ * <p>This method is called at least once before any samples are {@link #onSampleCompleted
+ * complete}. May be called multiple times after that in order to add {@link SeekPoint
+ * SeekPoints}.
+ *
* @param seekMap The extracted {@link SeekMap}.
*/
- void onSeekMap(SeekMap seekMap);
+ void onSeekMap(@NonNull SeekMap seekMap);
+
+ /**
+ * Called when the number of tracks is found.
+ *
+ * @param numberOfTracks The number of tracks in the stream.
+ */
+ void onTracksFound(int numberOfTracks);
/**
* Called when the {@link MediaFormat} of the track is extracted from the stream.
@@ -167,7 +300,7 @@
* @param trackIndex The index of the track for which the {@link MediaFormat} was found.
* @param format The extracted {@link MediaFormat}.
*/
- void onFormat(int trackIndex, MediaFormat format);
+ void onFormat(int trackIndex, @NonNull MediaFormat format);
/**
* Called to write sample data to the output.
@@ -176,16 +309,15 @@
* thrown {@link IOException} caused by reading from {@code input}.
*
* @param trackIndex The index of the track to which the sample data corresponds.
- * @param input The {@link Input} from which to read the data.
- * @return
+ * @param inputReader The {@link InputReader} from which to read the data.
*/
- int onSampleData(int trackIndex, Input input) throws IOException, InterruptedException;
+ void onSampleData(int trackIndex, @NonNull InputReader inputReader)
+ throws IOException, InterruptedException;
/**
- * Defines the boundaries and metadata of an extracted sample.
+ * Called once all the data of a sample has been passed to {@link #onSampleData}.
*
- * <p>The corresponding sample data will have already been passed to the output via calls to
- * {@link #onSampleData}.
+ * <p>Also includes sample metadata, like presentation timestamp and flags.
*
* @param trackIndex The index of the track to which the sample corresponds.
* @param timeUs The media timestamp associated with the sample, in microseconds.
@@ -203,57 +335,22 @@
int flags,
int size,
int offset,
- MediaCodec.CryptoInfo cryptoData);
- }
-
- /**
- * Controls the behavior of extractors' implementations.
- *
- * <p>DESIGN NOTE: For setting flags like workarounds and special behaviors for adaptive
- * streaming.
- */
- public static final class Parameters {
-
- // TODO: Implement.
-
- }
-
- /** Holds the result of an {@link #advance} invocation. */
- public static final class ResultHolder {
-
- /** Creates a new instance with {@link #result} holding {@link #ADVANCE_RESULT_CONTINUE}. */
- public ResultHolder() {
- result = ADVANCE_RESULT_CONTINUE;
- }
-
- /**
- * May hold {@link #ADVANCE_RESULT_END_OF_INPUT}, {@link #ADVANCE_RESULT_CONTINUE}, {@link
- * #ADVANCE_RESULT_SEEK}.
- */
- public int result;
-
- /**
- * If {@link #result} holds {@link #ADVANCE_RESULT_SEEK}, holds the stream position required
- * from the passed {@link Input} to the next {@link #advance} call. If {@link #result} does
- * not hold {@link #ADVANCE_RESULT_SEEK}, the value of this variable is undefined and should
- * be ignored.
- */
- public long seekPosition;
+ @Nullable MediaCodec.CryptoInfo cryptoData);
}
/**
* Thrown if all extractors implementations provided to {@link #create} failed to sniff the
* input content.
*/
- // @HiddenApi
public static final class UnrecognizedInputFormatException extends IOException {
/**
* Creates a new instance which signals that the extractors with the given names failed to
* parse the input.
*/
- public static UnrecognizedInputFormatException createForExtractors(
- String... extractorNames) {
+ @NonNull
+ private static UnrecognizedInputFormatException createForExtractors(
+ @NonNull String... extractorNames) {
StringBuilder builder = new StringBuilder();
builder.append("None of the available extractors ( ");
builder.append(extractorNames[0]);
@@ -270,21 +367,9 @@
}
}
- // Public constants.
+ // Private constants.
- /**
- * Returned by {@link #advance} if the {@link Input} passed to the next {@link #advance} is
- * required to provide data continuing from the position in the stream reached by the returning
- * call.
- */
- public static final int ADVANCE_RESULT_CONTINUE = -1;
- /** Returned by {@link #advance} if the end of the {@link Input} was reached. */
- public static final int ADVANCE_RESULT_END_OF_INPUT = -2;
- /**
- * Returned by {@link #advance} when its next call expects a specific stream position, which
- * will be held by {@link ResultHolder#seekPosition}.
- */
- public static final int ADVANCE_RESULT_SEEK = -3;
+ private static final Map<String, ExtractorFactory> EXTRACTOR_FACTORIES_BY_NAME;
// Instance creation methods.
@@ -293,13 +378,15 @@
* instance will attempt extraction without sniffing the content.
*
* @param name The name of the extractor that will be associated with the created instance.
- * @param outputCallback The {@link OutputCallback} to which track data and samples are pushed.
- * @param parameters Parameters that control specific aspects of the behavior of the extractors.
+ * @param outputConsumer The {@link OutputConsumer} to which track data and samples are pushed.
* @return A new instance.
+ * @throws IllegalArgumentException If an invalid name is provided.
*/
- public static MediaParser createByName(
- String name, OutputCallback outputCallback, Parameters parameters) {
- throw new UnsupportedOperationException();
+ public static @NonNull MediaParser createByName(
+ @NonNull String name, @NonNull OutputConsumer outputConsumer) {
+ String[] nameAsArray = new String[] {name};
+ assertValidNames(nameAsArray);
+ return new MediaParser(outputConsumer, /* sniff= */ false, name);
}
/**
@@ -307,30 +394,46 @@
* the first {@link #advance} call. Extractor implementations will sniff the content in order of
* appearance in {@code extractorNames}.
*
- * @param outputCallback The {@link OutputCallback} to track data and samples are obtained.
- * @param parameters Parameters that control specific aspects of the behavior of the extractors.
+ * @param outputConsumer The {@link OutputConsumer} to which extracted data is output.
* @param extractorNames The names of the extractors to sniff the content with. If empty, a
* default array of names is used.
* @return A new instance.
*/
- public static MediaParser create(
- OutputCallback outputCallback, Parameters parameters, String... extractorNames) {
- throw new UnsupportedOperationException();
+ public static @NonNull MediaParser create(
+ @NonNull OutputConsumer outputConsumer, @NonNull String... extractorNames) {
+ assertValidNames(extractorNames);
+ if (extractorNames.length == 0) {
+ extractorNames = EXTRACTOR_FACTORIES_BY_NAME.keySet().toArray(new String[0]);
+ }
+ return new MediaParser(outputConsumer, /* sniff= */ true, extractorNames);
}
// Misc static methods.
/**
* Returns an immutable list with the names of the extractors that are suitable for container
- * formats with the given {@code mimeTypes}. If an empty string is passed, all available
- * extractors' names are returned.
+ * formats with the given {@link MediaFormat}.
*
- * <p>TODO: Replace string with media type object.
+ * <p>TODO: List which properties are taken into account. E.g. MimeType.
*/
- public static List<String> getExtractorNames(String mimeTypes) {
+ public static @NonNull List<String> getExtractorNames(@NonNull MediaFormat mediaFormat) {
throw new UnsupportedOperationException();
}
+ // Private fields.
+
+ private final OutputConsumer mOutputConsumer;
+ private final String[] mExtractorNamesPool;
+ private final PositionHolder mPositionHolder;
+ private final InputReadingDataSource mDataSource;
+ private final ExtractorInputAdapter mScratchExtractorInputAdapter;
+ private final ParsableByteArrayAdapter mScratchParsableByteArrayAdapter;
+ private String mExtractorName;
+ private Extractor mExtractor;
+ private ExtractorInput mExtractorInput;
+ private long mPendingSeekPosition;
+ private long mPendingSeekTimeUs;
+
// Public methods.
/**
@@ -344,8 +447,8 @@
* @return The name of the backing extractor implementation, or null if the backing extractor
* implementation has not yet been selected.
*/
- public String getExtractorName() {
- throw new UnsupportedOperationException();
+ public @Nullable String getExtractorName() {
+ return mExtractorName;
}
/**
@@ -357,26 +460,85 @@
* <p>If this instance was created using {@link #create}. the first call to this method will
* sniff the content with the extractors with the provided names.
*
- * @param input The {@link Input} from which to obtain the media container data.
- * @param resultHolder The {@link ResultHolder} into which the result of the operation will be
- * written.
+ * @param seekableInputReader The {@link SeekableInputReader} from which to obtain the media
+ * container data.
+ * @return Whether there is any data left to extract. Returns false if the end of input has been
+ * reached.
* @throws UnrecognizedInputFormatException
*/
- public void advance(Input input, ResultHolder resultHolder)
+ public boolean advance(@NonNull SeekableInputReader seekableInputReader)
throws IOException, InterruptedException {
- throw new UnsupportedOperationException();
+ if (mExtractorInput == null) {
+ // TODO: For efficiency, the same implementation should be used, by providing a
+ // clearBuffers() method, or similar.
+ mExtractorInput =
+ new DefaultExtractorInput(
+ mDataSource,
+ seekableInputReader.getPosition(),
+ seekableInputReader.getLength());
+ }
+ mDataSource.mInputReader = seekableInputReader;
+
+ if (mExtractor == null) {
+ for (String extractorName : mExtractorNamesPool) {
+ Extractor extractor =
+ EXTRACTOR_FACTORIES_BY_NAME.get(extractorName).createInstance();
+ try {
+ if (extractor.sniff(mExtractorInput)) {
+ mExtractorName = extractorName;
+ mExtractor = extractor;
+ mExtractor.init(new ExtractorOutputAdapter());
+ break;
+ }
+ } catch (EOFException e) {
+ // Do nothing.
+ } catch (IOException | InterruptedException e) {
+ throw new IllegalStateException(e);
+ } finally {
+ mExtractorInput.resetPeekPosition();
+ }
+ }
+ if (mExtractor == null) {
+ UnrecognizedInputFormatException.createForExtractors(mExtractorNamesPool);
+ }
+ return true;
+ }
+
+ if (isPendingSeek()) {
+ mExtractor.seek(mPendingSeekPosition, mPendingSeekTimeUs);
+ removePendingSeek();
+ }
+
+ mPositionHolder.position = seekableInputReader.getPosition();
+ int result = mExtractor.read(mExtractorInput, mPositionHolder);
+ if (result == Extractor.RESULT_END_OF_INPUT) {
+ return false;
+ }
+ if (result == Extractor.RESULT_SEEK) {
+ mExtractorInput = null;
+ seekableInputReader.seekToPosition(mPositionHolder.position);
+ }
+ return true;
}
/**
* Seeks within the media container being extracted.
*
- * <p>Following a call to this method, the {@link Input} passed to the next invocation of {@link
- * #advance} must provide data starting from {@link SeekPoint#mPosition} in the stream.
+ * <p>{@link SeekPoint SeekPoints} can be obtained from the {@link SeekMap} passed to {@link
+ * OutputConsumer#onSeekMap(SeekMap)}.
+ *
+ * <p>Following a call to this method, the {@link InputReader} passed to the next invocation of
+ * {@link #advance} must provide data starting from {@link SeekPoint#position} in the stream.
*
* @param seekPoint The {@link SeekPoint} to seek to.
*/
- public void seek(SeekPoint seekPoint) {
- throw new UnsupportedOperationException();
+ public void seek(@NonNull SeekPoint seekPoint) {
+ if (mExtractor == null) {
+ mPendingSeekPosition = seekPoint.position;
+ mPendingSeekTimeUs = seekPoint.timeUs;
+ } else {
+ mExtractor.seek(seekPoint.position, seekPoint.timeUs);
+ }
}
/**
@@ -386,6 +548,359 @@
* invoked. DESIGN NOTE: Should be removed. There shouldn't be any resource for releasing.
*/
public void release() {
- throw new UnsupportedOperationException();
+ mExtractorInput = null;
+ mExtractor = null;
+ }
+
+ // Private methods.
+
+ private MediaParser(
+ OutputConsumer outputConsumer, boolean sniff, String... extractorNamesPool) {
+ mOutputConsumer = outputConsumer;
+ mExtractorNamesPool = extractorNamesPool;
+ if (!sniff) {
+ mExtractorName = extractorNamesPool[0];
+ mExtractor = EXTRACTOR_FACTORIES_BY_NAME.get(mExtractorName).createInstance();
+ }
+ mPositionHolder = new PositionHolder();
+ mDataSource = new InputReadingDataSource();
+ removePendingSeek();
+ mScratchExtractorInputAdapter = new ExtractorInputAdapter();
+ mScratchParsableByteArrayAdapter = new ParsableByteArrayAdapter();
+ }
+
+ private boolean isPendingSeek() {
+ return mPendingSeekPosition >= 0;
+ }
+
+ private void removePendingSeek() {
+ mPendingSeekPosition = -1;
+ mPendingSeekTimeUs = -1;
+ }
+
+ // Private classes.
+
+ private static final class InputReadingDataSource implements DataSource {
+
+ public InputReader mInputReader;
+
+ @Override
+ public void addTransferListener(TransferListener transferListener) {
+ // Do nothing.
+ }
+
+ @Override
+ public long open(DataSpec dataSpec) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int read(byte[] buffer, int offset, int readLength) throws IOException {
+ // TODO: Reevaluate interruption in Input.
+ try {
+ return mInputReader.read(buffer, offset, readLength);
+ } catch (InterruptedException e) {
+ // TODO: Remove.
+ throw new RuntimeException();
+ }
+ }
+
+ @Override
+ public Uri getUri() {
+ return null;
+ }
+
+ @Override
+ public Map<String, List<String>> getResponseHeaders() {
+ return null;
+ }
+
+ @Override
+ public void close() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private final class ExtractorOutputAdapter implements ExtractorOutput {
+
+ private final SparseArray<TrackOutput> mTrackOutputAdapters;
+ private boolean mTracksEnded;
+
+ private ExtractorOutputAdapter() {
+ mTrackOutputAdapters = new SparseArray<>();
+ }
+
+ @Override
+ public TrackOutput track(int id, int type) {
+ TrackOutput trackOutput = mTrackOutputAdapters.get(id);
+ if (trackOutput == null) {
+ trackOutput = new TrackOutputAdapter(mTrackOutputAdapters.size());
+ mTrackOutputAdapters.put(id, trackOutput);
+ }
+ return trackOutput;
+ }
+
+ @Override
+ public void endTracks() {
+ mOutputConsumer.onTracksFound(mTrackOutputAdapters.size());
+ }
+
+ @Override
+ public void seekMap(com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) {
+ mOutputConsumer.onSeekMap(new ExoToMediaParserSeekMapAdapter(exoplayerSeekMap));
+ }
+ }
+
+ private class TrackOutputAdapter implements TrackOutput {
+
+ private final int mTrackIndex;
+
+ private TrackOutputAdapter(int trackIndex) {
+ mTrackIndex = trackIndex;
+ }
+
+ @Override
+ public void format(Format format) {
+ mOutputConsumer.onFormat(mTrackIndex, toMediaFormat(format));
+ }
+
+ @Override
+ public int sampleData(ExtractorInput input, int length, boolean allowEndOfInput)
+ throws IOException, InterruptedException {
+ mScratchExtractorInputAdapter.setExtractorInput(input, length);
+ long positionBeforeReading = mScratchExtractorInputAdapter.getPosition();
+ mOutputConsumer.onSampleData(mTrackIndex, mScratchExtractorInputAdapter);
+ return (int) (mScratchExtractorInputAdapter.getPosition() - positionBeforeReading);
+ }
+
+ @Override
+ public void sampleData(ParsableByteArray data, int length) {
+ mScratchParsableByteArrayAdapter.resetWithByteArray(data, length);
+ try {
+ mOutputConsumer.onSampleData(mTrackIndex, mScratchParsableByteArrayAdapter);
+ } catch (IOException | InterruptedException e) {
+ // Unexpected.
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void sampleMetadata(
+ long timeUs, int flags, int size, int offset, CryptoData encryptionData) {
+ mOutputConsumer.onSampleCompleted(
+ mTrackIndex, timeUs, flags, size, offset, toCryptoInfo(encryptionData));
+ }
+ }
+
+ private static final class ExtractorInputAdapter implements InputReader {
+
+ private ExtractorInput mExtractorInput;
+ private int mCurrentPosition;
+ private long mLength;
+
+ public void setExtractorInput(ExtractorInput extractorInput, long length) {
+ mExtractorInput = extractorInput;
+ mCurrentPosition = 0;
+ mLength = length;
+ }
+
+ // Input implementation.
+
+ @Override
+ public int read(byte[] buffer, int offset, int readLength)
+ throws IOException, InterruptedException {
+ int readBytes = mExtractorInput.read(buffer, offset, readLength);
+ mCurrentPosition += readBytes;
+ return readBytes;
+ }
+
+ @Override
+ public long getPosition() {
+ return mCurrentPosition;
+ }
+
+ @Override
+ public long getLength() {
+ return mLength - mCurrentPosition;
+ }
+ }
+
+ private static final class ParsableByteArrayAdapter implements InputReader {
+
+ private ParsableByteArray mByteArray;
+ private long mLength;
+ private int mCurrentPosition;
+
+ public void resetWithByteArray(ParsableByteArray byteArray, long length) {
+ mByteArray = byteArray;
+ mCurrentPosition = 0;
+ mLength = length;
+ }
+
+ // Input implementation.
+
+ @Override
+ public int read(byte[] buffer, int offset, int readLength) {
+ mByteArray.readBytes(buffer, offset, readLength);
+ mCurrentPosition += readLength;
+ return readLength;
+ }
+
+ @Override
+ public long getPosition() {
+ return mCurrentPosition;
+ }
+
+ @Override
+ public long getLength() {
+ return mLength - mCurrentPosition;
+ }
+ }
+
+ /** Creates extractor instances. */
+ private interface ExtractorFactory {
+
+ /** Returns a new extractor instance. */
+ Extractor createInstance();
+ }
+
+ private static class ExoToMediaParserSeekMapAdapter implements SeekMap {
+
+ private final com.google.android.exoplayer2.extractor.SeekMap mExoPlayerSeekMap;
+
+ private ExoToMediaParserSeekMapAdapter(
+ com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) {
+ mExoPlayerSeekMap = exoplayerSeekMap;
+ }
+
+ @Override
+ public boolean isSeekable() {
+ return mExoPlayerSeekMap.isSeekable();
+ }
+
+ @Override
+ public long getDurationUs() {
+ return mExoPlayerSeekMap.getDurationUs();
+ }
+
+ @Override
+ public Pair<SeekPoint, SeekPoint> getSeekPoints(long timeUs) {
+ SeekPoints seekPoints = mExoPlayerSeekMap.getSeekPoints(timeUs);
+ return new Pair<>(toSeekPoint(seekPoints.first), toSeekPoint(seekPoints.second));
+ }
+ }
+
+ // Private static methods.
+
+ private static MediaFormat toMediaFormat(Format format) {
+
+ // TODO: Add if (value != Format.NO_VALUE);
+
+ MediaFormat result = new MediaFormat();
+ result.setInteger(MediaFormat.KEY_BIT_RATE, format.bitrate);
+ result.setInteger(MediaFormat.KEY_CHANNEL_COUNT, format.channelCount);
+ if (format.colorInfo != null) {
+ result.setInteger(MediaFormat.KEY_COLOR_TRANSFER, format.colorInfo.colorTransfer);
+ result.setInteger(MediaFormat.KEY_COLOR_RANGE, format.colorInfo.colorRange);
+ result.setInteger(MediaFormat.KEY_COLOR_STANDARD, format.colorInfo.colorSpace);
+ if (format.colorInfo.hdrStaticInfo != null) {
+ result.setByteBuffer(
+ MediaFormat.KEY_HDR_STATIC_INFO,
+ ByteBuffer.wrap(format.colorInfo.hdrStaticInfo));
+ }
+ }
+ result.setString(MediaFormat.KEY_MIME, format.sampleMimeType);
+ result.setFloat(MediaFormat.KEY_FRAME_RATE, format.frameRate);
+ result.setInteger(MediaFormat.KEY_WIDTH, format.width);
+ result.setInteger(MediaFormat.KEY_HEIGHT, format.height);
+ List<byte[]> initData = format.initializationData;
+ if (initData != null) {
+ for (int i = 0; i < initData.size(); i++) {
+ result.setByteBuffer("csd-" + i, ByteBuffer.wrap(initData.get(i)));
+ }
+ }
+ result.setString(MediaFormat.KEY_LANGUAGE, format.language);
+ result.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, format.maxInputSize);
+ result.setInteger(MediaFormat.KEY_PCM_ENCODING, format.pcmEncoding);
+ result.setInteger(MediaFormat.KEY_ROTATION, format.rotationDegrees);
+ result.setInteger(MediaFormat.KEY_SAMPLE_RATE, format.sampleRate);
+
+ int selectionFlags = format.selectionFlags;
+ // We avoid setting selection flags in the MediaFormat, unless explicitly signaled by the
+ // extractor.
+ if ((selectionFlags & C.SELECTION_FLAG_AUTOSELECT) != 0) {
+ result.setInteger(MediaFormat.KEY_IS_AUTOSELECT, 1);
+ }
+ if ((selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0) {
+ result.setInteger(MediaFormat.KEY_IS_DEFAULT, 1);
+ }
+ if ((selectionFlags & C.SELECTION_FLAG_FORCED) != 0) {
+ result.setInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, 1);
+ }
+
+ // LACK OF SUPPORT FOR:
+ // format.accessibilityChannel;
+ // format.codecs;
+ // format.containerMimeType;
+ // format.drmInitData;
+ // format.encoderDelay;
+ // format.encoderPadding;
+ // format.id;
+ // format.metadata;
+ // format.pixelWidthHeightRatio;
+ // format.roleFlags;
+ // format.stereoMode;
+ // format.subsampleOffsetUs;
+ return result;
+ }
+
+ private static int toFrameworkFlags(int flags) {
+ // TODO: Implement.
+ return 0;
+ }
+
+ private static MediaCodec.CryptoInfo toCryptoInfo(TrackOutput.CryptoData encryptionData) {
+ // TODO: Implement.
+ return null;
+ }
+
+ /** Returns a new {@link SeekPoint} equivalent to the given {@code exoPlayerSeekPoint}. */
+ private static SeekPoint toSeekPoint(
+ com.google.android.exoplayer2.extractor.SeekPoint exoPlayerSeekPoint) {
+ return new SeekPoint(exoPlayerSeekPoint.timeUs, exoPlayerSeekPoint.position);
+ }
+
+ private static void assertValidNames(@NonNull String[] names) {
+ for (String name : names) {
+ if (!EXTRACTOR_FACTORIES_BY_NAME.containsKey(name)) {
+ throw new IllegalArgumentException(
+ "Invalid extractor name: "
+ + name
+ + ". Supported extractors are: "
+ + TextUtils.join(", ", EXTRACTOR_FACTORIES_BY_NAME.keySet())
+ + ".");
+ }
+ }
+ }
+
+ // Static initialization.
+
+ static {
+ // Using a LinkedHashMap to keep the insertion order when iterating over the keys.
+ LinkedHashMap<String, ExtractorFactory> extractorFactoriesByName = new LinkedHashMap<>();
+ extractorFactoriesByName.put("exo.Ac3Extractor", Ac3Extractor::new);
+ extractorFactoriesByName.put("exo.Ac4Extractor", Ac4Extractor::new);
+ extractorFactoriesByName.put("exo.AdtsExtractor", AdtsExtractor::new);
+ extractorFactoriesByName.put("exo.AmrExtractor", AmrExtractor::new);
+ extractorFactoriesByName.put("exo.FlvExtractor", FlvExtractor::new);
+ extractorFactoriesByName.put("exo.FragmentedMp4Extractor", FragmentedMp4Extractor::new);
+ extractorFactoriesByName.put("exo.MatroskaExtractor", MatroskaExtractor::new);
+ extractorFactoriesByName.put("exo.Mp3Extractor", Mp3Extractor::new);
+ extractorFactoriesByName.put("exo.Mp4Extractor", Mp4Extractor::new);
+ extractorFactoriesByName.put("exo.OggExtractor", OggExtractor::new);
+ extractorFactoriesByName.put("exo.PsExtractor", PsExtractor::new);
+ extractorFactoriesByName.put("exo.TsExtractor", TsExtractor::new);
+ extractorFactoriesByName.put("exo.WavExtractor", WavExtractor::new);
+ EXTRACTOR_FACTORIES_BY_NAME = Collections.unmodifiableMap(extractorFactoriesByName);
}
}
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 3a092a0..c03e8e2 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -388,12 +388,21 @@
*/
public static final int FLAG_NO_SYSTEM_CAPTURE = 0x1 << 12;
+ /**
+ * @hide
+ * Flag requesting private audio capture. When set in audio attributes passed to an
+ * AudioRecord, this prevents a privileged Assistant from capturing audio while this
+ * AudioRecord is active.
+ */
+ public static final int FLAG_CAPTURE_PRIVATE = 0x1 << 13;
+
+
// Note that even though FLAG_MUTE_HAPTIC is stored as a flag bit, it is not here since
// it is known as a boolean value outside of AudioAttributes.
private static final int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO
| FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY
| FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER | FLAG_NO_MEDIA_PROJECTION
- | FLAG_NO_SYSTEM_CAPTURE;
+ | FLAG_NO_SYSTEM_CAPTURE | FLAG_CAPTURE_PRIVATE;
private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED |
FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY;
@@ -620,6 +629,12 @@
if (mMuteHapticChannels) {
aa.mFlags |= FLAG_MUTE_HAPTIC;
}
+ // capturing for camcorder of communication is private by default to
+ // reflect legacy behavior
+ if (aa.mSource == MediaRecorder.AudioSource.VOICE_COMMUNICATION
+ || aa.mSource == MediaRecorder.AudioSource.CAMCORDER) {
+ aa.mFlags |= FLAG_CAPTURE_PRIVATE;
+ }
aa.mTags = (HashSet<String>) mTags.clone();
aa.mFormattedTags = TextUtils.join(";", mTags);
if (mBundle != null) {
@@ -1062,7 +1077,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(AudioAttributesProto.USAGE, mUsage);
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 0254c97..95afb09 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -527,6 +527,11 @@
private AudioFormat mFormat;
private int mBufferSizeInBytes;
private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
+ private int mPrivacySensitive = PRIVACY_SENSITIVE_DEFAULT;
+
+ private static final int PRIVACY_SENSITIVE_DEFAULT = -1;
+ private static final int PRIVACY_SENSITIVE_DISABLED = 0;
+ private static final int PRIVACY_SENSITIVE_ENABLED = 1;
/**
* Constructs a new Builder with the default values as described above.
@@ -632,6 +637,36 @@
}
/**
+ * Indicates that this capture request is privacy sensitive and that
+ * any concurrent capture is not permitted.
+ * <p>
+ * The default is not privacy sensitive except when the audio source set with
+ * {@link #setAudioSource(int)} is {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION} or
+ * {@link MediaRecorder.AudioSource#CAMCORDER}.
+ * <p>
+ * Always takes precedence over default from audio source when set explicitly.
+ * <p>
+ * Using this API is only permitted when the audio source is one of:
+ * <ul>
+ * <li>{@link MediaRecorder.AudioSource#MIC}</li>
+ * <li>{@link MediaRecorder.AudioSource#CAMCORDER}</li>
+ * <li>{@link MediaRecorder.AudioSource#VOICE_RECOGNITION}</li>
+ * <li>{@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}</li>
+ * <li>{@link MediaRecorder.AudioSource#UNPROCESSED}</li>
+ * <li>{@link MediaRecorder.AudioSource#VOICE_PERFORMANCE}</li>
+ * </ul>
+ * Invoking {@link #build()} will throw an UnsupportedOperationException if this
+ * condition is not met.
+ * @param privacySensitive True if capture from this AudioRecord must be marked as privacy
+ * sensitive, false otherwise.
+ */
+ public @NonNull Builder setPrivacySensitive(boolean privacySensitive) {
+ mPrivacySensitive =
+ privacySensitive ? PRIVACY_SENSITIVE_ENABLED : PRIVACY_SENSITIVE_DISABLED;
+ return this;
+ }
+
+ /**
* @hide
* To be only used by system components.
* @param sessionId ID of audio session the AudioRecord must be attached to, or
@@ -704,6 +739,34 @@
.setInternalCapturePreset(MediaRecorder.AudioSource.DEFAULT)
.build();
}
+
+ // If mPrivacySensitive is default, the privacy flag is already set
+ // according to audio source in audio attributes.
+ if (mPrivacySensitive != PRIVACY_SENSITIVE_DEFAULT) {
+ int source = mAttributes.getCapturePreset();
+ if (source == MediaRecorder.AudioSource.REMOTE_SUBMIX
+ || source == MediaRecorder.AudioSource.RADIO_TUNER
+ || source == MediaRecorder.AudioSource.VOICE_DOWNLINK
+ || source == MediaRecorder.AudioSource.VOICE_UPLINK
+ || source == MediaRecorder.AudioSource.VOICE_CALL
+ || source == MediaRecorder.AudioSource.ECHO_REFERENCE) {
+ throw new UnsupportedOperationException(
+ "Cannot request private capture with source: " + source);
+ }
+
+ int flags = mAttributes.getAllFlags();
+ if (mPrivacySensitive == PRIVACY_SENSITIVE_DISABLED) {
+ flags &= ~AudioAttributes.FLAG_CAPTURE_PRIVATE;
+ } else if (mPrivacySensitive == PRIVACY_SENSITIVE_ENABLED) {
+ flags |= AudioAttributes.FLAG_CAPTURE_PRIVATE;
+ }
+ if (flags != mAttributes.getAllFlags()) {
+ mAttributes = new AudioAttributes.Builder(mAttributes)
+ .replaceFlags(flags)
+ .build();
+ }
+ }
+
try {
// If the buffer size is not specified,
// use a single frame for the buffer size and let the
@@ -1062,6 +1125,17 @@
return mSessionId;
}
+ /**
+ * Returns whether this AudioRecord is marked as privacy sensitive or not.
+ * <p>
+ * See {@link Builder#setPrivacySensitive(boolean)}
+ * <p>
+ * @return true if privacy sensitive, false otherwise
+ */
+ public boolean isPrivacySensitive() {
+ return (mAudioAttributes.getAllFlags() & AudioAttributes.FLAG_CAPTURE_PRIVATE) != 0;
+ }
+
//---------------------------------------------------------
// Transport control methods
//--------------------
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 9723652..abb8206 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -587,6 +587,46 @@
}
/**
+ * Indicates that this capture request is privacy sensitive and that
+ * any concurrent capture is not permitted.
+ * <p>
+ * The default is not privacy sensitive except when the audio source set with
+ * {@link #setAudioSource(int)} is {@link AudioSource#VOICE_COMMUNICATION} or
+ * {@link AudioSource#CAMCORDER}.
+ * <p>
+ * Always takes precedence over default from audio source when set explicitly.
+ * <p>
+ * Using this API is only permitted when the audio source is one of:
+ * <ul>
+ * <li>{@link AudioSource#MIC}</li>
+ * <li>{@link AudioSource#CAMCORDER}</li>
+ * <li>{@link AudioSource#VOICE_RECOGNITION}</li>
+ * <li>{@link AudioSource#VOICE_COMMUNICATION}</li>
+ * <li>{@link AudioSource#UNPROCESSED}</li>
+ * <li>{@link AudioSource#VOICE_PERFORMANCE}</li>
+ * </ul>
+ * Invoking {@link #prepare()} will throw an IOException if this
+ * condition is not met.
+ * <p>
+ * Must be called after {@link #setAudioSource(int)} and before {@link #setOutputFormat(int)}.
+ * @param privacySensitive True if capture from this MediaRecorder must be marked as privacy
+ * sensitive, false otherwise.
+ * @throws IllegalStateException if called before {@link #setAudioSource(int)}
+ * or after {@link #setOutputFormat(int)}
+ */
+ public native void setPrivacySensitive(boolean privacySensitive);
+
+ /**
+ * Returns whether this MediaRecorder is marked as privacy sensitive or not with
+ * regard to audio capture.
+ * <p>
+ * See {@link #setPrivacySensitive(boolean)}
+ * <p>
+ * @return true if privacy sensitive, false otherwise
+ */
+ public native boolean isPrivacySensitive();
+
+ /**
* Sets the video source to be used for recording. If this method is not
* called, the output file will not contain an video track. The source needs
* to be specified before setting recording-parameters or encoders. Call
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 24fff06..f8ba36d 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -227,6 +227,36 @@
}
static void
+android_media_MediaRecorder_setPrivacySensitive(JNIEnv *env, jobject thiz, jboolean privacySensitive)
+{
+ ALOGV("%s(%s)", __func__, privacySensitive ? "true" : "false");
+
+ sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
+ if (mr == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+ process_media_recorder_call(env, mr->setPrivacySensitive(privacySensitive),
+ "java/lang/RuntimeException", "setPrivacySensitive failed.");
+}
+
+static jboolean
+android_media_MediaRecorder_isPrivacySensitive(JNIEnv *env, jobject thiz)
+{
+ sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
+ if (mr == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return false;
+ }
+ bool privacySensitive;
+ process_media_recorder_call(env, mr->isPrivacySensitive(&privacySensitive),
+ "java/lang/RuntimeException", "isPrivacySensitive failed.");
+
+ ALOGV("%s() -> %s", __func__, privacySensitive ? "true" : "false");
+ return privacySensitive;
+}
+
+static void
android_media_MediaRecorder_setOutputFormat(JNIEnv *env, jobject thiz, jint of)
{
ALOGV("setOutputFormat(%d)", of);
@@ -817,6 +847,8 @@
{"setCamera", "(Landroid/hardware/Camera;)V", (void *)android_media_MediaRecorder_setCamera},
{"setVideoSource", "(I)V", (void *)android_media_MediaRecorder_setVideoSource},
{"setAudioSource", "(I)V", (void *)android_media_MediaRecorder_setAudioSource},
+ {"setPrivacySensitive", "(Z)V", (void *)android_media_MediaRecorder_setPrivacySensitive},
+ {"isPrivacySensitive", "()Z", (void *)android_media_MediaRecorder_isPrivacySensitive},
{"setOutputFormat", "(I)V", (void *)android_media_MediaRecorder_setOutputFormat},
{"setVideoEncoder", "(I)V", (void *)android_media_MediaRecorder_setVideoEncoder},
{"setAudioEncoder", "(I)V", (void *)android_media_MediaRecorder_setAudioEncoder},
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index bcb76d7..c8532e0 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -119,11 +119,11 @@
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarComponent;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
-import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -140,6 +140,7 @@
import java.util.Optional;
import javax.inject.Named;
+import javax.inject.Provider;
import dagger.Lazy;
@@ -156,7 +157,6 @@
private static final float FLING_SPEED_UP_FACTOR = 0.6f;
private final ScrimController mScrimController;
- private final StatusBarWindowViewController mStatusBarWindowViewController;
private final LockscreenLockIconController mLockscreenLockIconController;
private float mOpeningVelocity = DEFAULT_FLING_VELOCITY;
@@ -174,7 +174,6 @@
private final Object mQueueLock = new Object();
private final CarNavigationBarController mCarNavigationBarController;
- private final Lazy<DrivingStateHelper> mDrivingStateHelperLazy;
private final Lazy<PowerManagerHelper> mPowerManagerHelperLazy;
private final CarServiceProvider mCarServiceProvider;
@@ -289,7 +288,6 @@
NotificationListener notificationListener,
ConfigurationController configurationController,
StatusBarWindowController statusBarWindowController,
- StatusBarWindowViewController statusBarWindowViewController,
LockscreenLockIconController lockscreenLockIconController,
DozeParameters dozeParameters,
ScrimController scrimController,
@@ -302,6 +300,7 @@
VolumeComponent volumeComponent,
CommandQueue commandQueue,
Optional<Recents> recents,
+ Provider<StatusBarComponent.Builder> statusBarComponentBuilder,
PluginManager pluginManager,
RemoteInputUriController remoteInputUriController,
Optional<Divider> dividerOptional,
@@ -314,7 +313,6 @@
DismissCallbackRegistry dismissCallbackRegistry,
/* Car Settings injected components. */
CarServiceProvider carServiceProvider,
- Lazy<DrivingStateHelper> drivingStateHelperLazy,
Lazy<PowerManagerHelper> powerManagerHelperLazy,
Lazy<FullscreenUserSwitcher> fullscreenUserSwitcherLazy,
CarNavigationBarController carNavigationBarController) {
@@ -368,7 +366,6 @@
notificationListener,
configurationController,
statusBarWindowController,
- statusBarWindowViewController,
lockscreenLockIconController,
dozeParameters,
scrimController,
@@ -382,6 +379,7 @@
volumeComponent,
commandQueue,
recents,
+ statusBarComponentBuilder,
pluginManager,
remoteInputUriController,
dividerOptional,
@@ -392,11 +390,9 @@
viewMediatorCallback,
dismissCallbackRegistry);
mScrimController = scrimController;
- mStatusBarWindowViewController = statusBarWindowViewController;
mLockscreenLockIconController = lockscreenLockIconController;
mDeviceProvisionedController = deviceProvisionedController;
mCarServiceProvider = carServiceProvider;
- mDrivingStateHelperLazy = drivingStateHelperLazy;
mPowerManagerHelperLazy = powerManagerHelperLazy;
mFullscreenUserSwitcherLazy = fullscreenUserSwitcherLazy;
mCarNavigationBarController = carNavigationBarController;
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
index 6529868..eff60fa 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
@@ -78,11 +78,11 @@
import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.StatusBarComponent;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
-import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -96,6 +96,7 @@
import java.util.Optional;
import javax.inject.Named;
+import javax.inject.Provider;
import javax.inject.Singleton;
import dagger.Lazy;
@@ -162,7 +163,6 @@
NotificationListener notificationListener,
ConfigurationController configurationController,
StatusBarWindowController statusBarWindowController,
- StatusBarWindowViewController statusBarWindowViewController,
LockscreenLockIconController lockscreenLockIconController,
DozeParameters dozeParameters,
ScrimController scrimController,
@@ -175,6 +175,7 @@
VolumeComponent volumeComponent,
CommandQueue commandQueue,
Optional<Recents> recentsOptional,
+ Provider<StatusBarComponent.Builder> statusBarComponentBuilder,
PluginManager pluginManager,
RemoteInputUriController remoteInputUriController,
Optional<Divider> dividerOptional,
@@ -186,7 +187,6 @@
ViewMediatorCallback viewMediatorCallback,
DismissCallbackRegistry dismissCallbackRegistry,
CarServiceProvider carServiceProvider,
- Lazy<DrivingStateHelper> drivingStateHelperLazy,
Lazy<PowerManagerHelper> powerManagerHelperLazy,
Lazy<FullscreenUserSwitcher> fullscreenUserSwitcherLazy,
CarNavigationBarController carNavigationBarController) {
@@ -240,7 +240,6 @@
notificationListener,
configurationController,
statusBarWindowController,
- statusBarWindowViewController,
lockscreenLockIconController,
dozeParameters,
scrimController,
@@ -253,6 +252,7 @@
volumeComponent,
commandQueue,
recentsOptional,
+ statusBarComponentBuilder,
pluginManager,
remoteInputUriController,
dividerOptional,
@@ -263,7 +263,6 @@
viewMediatorCallback,
dismissCallbackRegistry,
carServiceProvider,
- drivingStateHelperLazy,
powerManagerHelperLazy,
fullscreenUserSwitcherLazy,
carNavigationBarController);
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
deleted file mode 100644
index 60934ab..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.car;
-
-import android.car.Car;
-import android.car.drivingstate.CarDrivingStateEvent;
-import android.car.drivingstate.CarDrivingStateManager;
-import android.car.drivingstate.CarDrivingStateManager.CarDrivingStateEventListener;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.android.systemui.car.CarServiceProvider;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * Helper class for connecting to the {@link CarDrivingStateManager} and listening for driving state
- * changes.
- */
-@Singleton
-public class DrivingStateHelper {
- public static final String TAG = "DrivingStateHelper";
-
- private final CarServiceProvider mCarServiceProvider;
-
- private CarDrivingStateManager mDrivingStateManager;
- private CarDrivingStateEventListener mDrivingStateHandler;
-
- @Inject
- public DrivingStateHelper(CarServiceProvider carServiceProvider) {
- mCarServiceProvider = carServiceProvider;
- }
-
- /**
- * Sets the {@link CarDrivingStateEventListener}. Should be set before calling {@link
- * #connectToCarService()}.
- */
- public void setCarDrivingStateEventListener(
- @NonNull CarDrivingStateEventListener carDrivingStateEventListener) {
- mDrivingStateHandler = carDrivingStateEventListener;
- }
-
- /**
- * Queries {@link CarDrivingStateManager} for current driving state. Returns {@code true} if car
- * is idling or moving, {@code false} otherwise.
- */
- public boolean isCurrentlyDriving() {
- if (mDrivingStateManager == null) {
- return false;
- }
- CarDrivingStateEvent currentState = mDrivingStateManager.getCurrentCarDrivingState();
- if (currentState != null) {
- return currentState.eventValue == CarDrivingStateEvent.DRIVING_STATE_IDLING
- || currentState.eventValue == CarDrivingStateEvent.DRIVING_STATE_MOVING;
- }
- return false; // Default to false.
- }
-
- /**
- * Establishes connection with the Car service.
- */
- public void connectToCarService() {
- mCarServiceProvider.addListener(mCarServiceLifecycleListener);
- }
-
- private final CarServiceProvider.CarServiceOnConnectedListener mCarServiceLifecycleListener =
- car -> {
- logD("Car Service connected");
- mDrivingStateManager = (CarDrivingStateManager) car.getCarManager(
- Car.CAR_DRIVING_STATE_SERVICE);
- if (mDrivingStateManager != null) {
- mDrivingStateManager.registerListener(mDrivingStateHandler);
- mDrivingStateHandler.onDrivingStateChanged(
- mDrivingStateManager.getCurrentCarDrivingState());
- } else {
- Log.e(TAG, "CarDrivingStateService service not available");
- }
- };
-
- private void logD(String message) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, message);
- }
- }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 785dd56..96aee51 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -44,8 +44,8 @@
private final CachedBluetoothDeviceManager mDeviceManager;
static final ParcelUuid[] SINK_UUIDS = {
- BluetoothUuid.AudioSink,
- BluetoothUuid.AdvAudioDist,
+ BluetoothUuid.A2DP_SINK,
+ BluetoothUuid.ADV_AUDIO_DIST,
};
static final String NAME = "A2DP";
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
index 4ce9d3e..55765dd 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
@@ -40,8 +40,8 @@
private final CachedBluetoothDeviceManager mDeviceManager;
static final ParcelUuid[] SRC_UUIDS = {
- BluetoothUuid.AudioSource,
- BluetoothUuid.AdvAudioDist,
+ BluetoothUuid.A2DP_SOURCE,
+ BluetoothUuid.ADV_AUDIO_DIST,
};
static final String NAME = "A2DPSink";
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDeviceFilter.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDeviceFilter.java
index 8dec86a..b8ad321 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDeviceFilter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothDeviceFilter.java
@@ -22,6 +22,8 @@
import android.os.ParcelUuid;
import android.util.Log;
+import com.android.internal.util.ArrayUtils;
+
/**
* BluetoothDeviceFilter contains a static method that returns a
* Filter object that returns whether or not the BluetoothDevice
@@ -130,7 +132,7 @@
@Override
boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
if (uuids != null) {
- if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush)) {
+ if (ArrayUtils.contains(uuids, BluetoothUuid.OBEX_OBJECT_PUSH)) {
return true;
}
}
@@ -144,7 +146,7 @@
@Override
boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
if (uuids != null) {
- if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.PANU)) {
+ if (ArrayUtils.contains(uuids, BluetoothUuid.PANU)) {
return true;
}
}
@@ -158,7 +160,7 @@
@Override
boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
if (uuids != null) {
- if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.NAP)) {
+ if (ArrayUtils.contains(uuids, BluetoothUuid.NAP)) {
return true;
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 833c4ac..0666596 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -35,6 +35,7 @@
import androidx.annotation.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.settingslib.R;
import com.android.settingslib.Utils;
@@ -685,9 +686,9 @@
ParcelUuid[] uuids = mDevice.getUuids();
long timeout = MAX_UUID_DELAY_FOR_AUTO_CONNECT;
- if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hogp)) {
+ if (ArrayUtils.contains(uuids, BluetoothUuid.HOGP)) {
timeout = MAX_HOGP_DELAY_FOR_AUTO_CONNECT;
- } else if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HearingAid)) {
+ } else if (ArrayUtils.contains(uuids, BluetoothUuid.HEARING_AID)) {
timeout = MAX_HEARING_AIDS_DELAY_FOR_AUTO_CONNECT;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
index c1933fd..9f7b718 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
@@ -45,7 +45,7 @@
static final ParcelUuid[] UUIDS = {
BluetoothUuid.HSP,
- BluetoothUuid.Handsfree,
+ BluetoothUuid.HFP,
};
static final String NAME = "HEADSET";
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
index 4bdbc31..860b77d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
@@ -44,7 +44,7 @@
static final ParcelUuid[] SRC_UUIDS = {
BluetoothUuid.HSP_AG,
- BluetoothUuid.Handsfree_AG,
+ BluetoothUuid.HFP_AG,
};
static final String NAME = "HEADSET_CLIENT";
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 29c6d71..ae2acbe 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -30,8 +30,8 @@
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothPbap;
import android.bluetooth.BluetoothPbapClient;
-import android.bluetooth.BluetoothSap;
import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothSap;
import android.bluetooth.BluetoothUuid;
import android.content.Context;
import android.content.Intent;
@@ -40,6 +40,7 @@
import androidx.annotation.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
import java.util.ArrayList;
@@ -471,43 +472,40 @@
}
if (mHeadsetProfile != null) {
- if ((BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.HSP_AG) &&
- BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP)) ||
- (BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.Handsfree_AG) &&
- BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree))) {
+ if ((ArrayUtils.contains(localUuids, BluetoothUuid.HSP_AG)
+ && ArrayUtils.contains(uuids, BluetoothUuid.HSP))
+ || (ArrayUtils.contains(localUuids, BluetoothUuid.HFP_AG)
+ && ArrayUtils.contains(uuids, BluetoothUuid.HFP))) {
profiles.add(mHeadsetProfile);
removedProfiles.remove(mHeadsetProfile);
}
}
if ((mHfpClientProfile != null) &&
- BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) &&
- BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.Handsfree)) {
+ ArrayUtils.contains(uuids, BluetoothUuid.HFP_AG)
+ && ArrayUtils.contains(localUuids, BluetoothUuid.HFP)) {
profiles.add(mHfpClientProfile);
removedProfiles.remove(mHfpClientProfile);
}
- if (BluetoothUuid.containsAnyUuid(uuids, A2dpProfile.SINK_UUIDS) &&
- mA2dpProfile != null) {
+ if (BluetoothUuid.containsAnyUuid(uuids, A2dpProfile.SINK_UUIDS) && mA2dpProfile != null) {
profiles.add(mA2dpProfile);
removedProfiles.remove(mA2dpProfile);
}
- if (BluetoothUuid.containsAnyUuid(uuids, A2dpSinkProfile.SRC_UUIDS) &&
- mA2dpSinkProfile != null) {
+ if (BluetoothUuid.containsAnyUuid(uuids, A2dpSinkProfile.SRC_UUIDS)
+ && mA2dpSinkProfile != null) {
profiles.add(mA2dpSinkProfile);
removedProfiles.remove(mA2dpSinkProfile);
}
- if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush) &&
- mOppProfile != null) {
+ if (ArrayUtils.contains(uuids, BluetoothUuid.OBEX_OBJECT_PUSH) && mOppProfile != null) {
profiles.add(mOppProfile);
removedProfiles.remove(mOppProfile);
}
- if ((BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hid) ||
- BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hogp)) &&
- mHidProfile != null) {
+ if ((ArrayUtils.contains(uuids, BluetoothUuid.HID)
+ || ArrayUtils.contains(uuids, BluetoothUuid.HOGP)) && mHidProfile != null) {
profiles.add(mHidProfile);
removedProfiles.remove(mHidProfile);
}
@@ -520,8 +518,8 @@
if(isPanNapConnected)
if(DEBUG) Log.d(TAG, "Valid PAN-NAP connection exists.");
- if ((BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.NAP) &&
- mPanProfile != null) || isPanNapConnected) {
+ if ((ArrayUtils.contains(uuids, BluetoothUuid.NAP) && mPanProfile != null)
+ || isPanNapConnected) {
profiles.add(mPanProfile);
removedProfiles.remove(mPanProfile);
}
@@ -545,20 +543,18 @@
removedProfiles.remove(mMapClientProfile);
}
- if ((mPbapClientProfile != null) &&
- BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.PBAP_PCE) &&
- BluetoothUuid.containsAnyUuid(uuids, PbapClientProfile.SRC_UUIDS)) {
+ if ((mPbapClientProfile != null) && ArrayUtils.contains(localUuids, BluetoothUuid.PBAP_PCE)
+ && BluetoothUuid.containsAnyUuid(uuids, PbapClientProfile.SRC_UUIDS)) {
profiles.add(mPbapClientProfile);
removedProfiles.remove(mPbapClientProfile);
}
- if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HearingAid) &&
- mHearingAidProfile != null) {
+ if (ArrayUtils.contains(uuids, BluetoothUuid.HEARING_AID) && mHearingAidProfile != null) {
profiles.add(mHearingAidProfile);
removedProfiles.remove(mHearingAidProfile);
}
- if (mSapProfile != null && BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.SAP)) {
+ if (mSapProfile != null && ArrayUtils.contains(uuids, BluetoothUuid.SAP)) {
profiles.add(mSapProfile);
removedProfiles.remove(mSapProfile);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
index 17104e4..d91226e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
@@ -46,7 +46,7 @@
// The UUIDs indicate that remote device might access pbap server
static final ParcelUuid[] PBAB_CLIENT_UUIDS = {
BluetoothUuid.HSP,
- BluetoothUuid.Handsfree,
+ BluetoothUuid.HFP,
BluetoothUuid.PBAP_PCE
};
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
index 5d5872e..fd5b053 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
@@ -132,7 +132,7 @@
mShadowBluetoothAdapter.setSupportedProfiles(generateList(
new int[] {BluetoothProfile.HID_HOST}));
mProfileManager.updateLocalProfiles();
- ParcelUuid[] uuids = new ParcelUuid[]{BluetoothUuid.Hid};
+ ParcelUuid[] uuids = new ParcelUuid[]{BluetoothUuid.HID};
ParcelUuid[] localUuids = new ParcelUuid[]{};
List<LocalBluetoothProfile> profiles = new ArrayList<>();
List<LocalBluetoothProfile> removedProfiles = new ArrayList<>();
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
index 1527de1..1f68742 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -70,5 +70,7 @@
Settings.Global.CHARGING_VIBRATION_ENABLED,
Settings.Global.AWARE_ALLOWED,
Settings.Global.NOTIFICATION_BUBBLES,
+ Settings.Global.CUSTOM_BUGREPORT_HANDLER_APP,
+ Settings.Global.CUSTOM_BUGREPORT_HANDLER_USER,
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index 4a0ed6f..3d278db 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -149,5 +149,7 @@
VALIDATORS.put(
Global.POWER_BUTTON_VERY_LONG_PRESS, new InclusiveIntegerRangeValidator(0, 1));
VALIDATORS.put(Global.NOTIFICATION_BUBBLES, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.CUSTOM_BUGREPORT_HANDLER_APP, ANY_STRING_VALIDATOR);
+ VALIDATORS.put(Global.CUSTOM_BUGREPORT_HANDLER_USER, ANY_INTEGER_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 540726b..c23a494 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -268,6 +268,7 @@
Settings.Global.ERROR_LOGCAT_PREFIX,
Settings.Global.EUICC_PROVISIONED,
Settings.Global.EUICC_SUPPORTED_COUNTRIES,
+ Settings.Global.EUICC_UNSUPPORTED_COUNTRIES,
Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
Settings.Global.EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS,
Settings.Global.FANCY_IME_ANIMATIONS,
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 0c582c4..2a5bdc7 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -37,6 +37,7 @@
"src/**/I*.aidl",
],
resource_dirs: [
+ "res-product",
"res-keyguard",
"res",
],
@@ -91,6 +92,7 @@
manifest: "tests/AndroidManifest.xml",
resource_dirs: [
"tests/res",
+ "res-product",
"res-keyguard",
"res",
],
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 0a671d9..6f68038 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -288,6 +288,11 @@
android:exported="false"
android:permission="com.android.systemui.permission.SELF" />
+ <service android:name=".assist.AssistHandleService"
+ android:exported="true"
+ android:enabled="false"
+ />
+
<!-- started from PhoneWindowManager
TODO: Should have an android:permission attribute -->
<service android:name=".screenshot.TakeScreenshotService"
diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml
index b285f11..b7f29a1 100644
--- a/packages/SystemUI/res-keyguard/values-af/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-af/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Druk Kieslys om te ontsluit."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Netwerk is gesluit"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Geen SIM-kaart nie"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Geen SIM-kaart in tablet nie."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Geen SIM-kaart in foon nie."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Steek \'n SIM-kaart in."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Die SIM-kaart is weg of nie leesbaar nie. Steek \'n SIM-kaart in."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Onbruikbare SIM-kaart."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Tik \'n PIN wat 4 to 8 syfers lank is, in."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-kode moet 8 of meer syfers wees."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Voer die korrekte PUK-kode weer in. Herhaalde pogings sal die SIM permanent deaktiveer."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-kodes stem nie ooreen nie"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Te veel patroonpogings"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Jy het jou PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd ingetik. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%2$d</xliff:g> sekondes."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Jy het jou wagwoord <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd ingetik. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%2$d</xliff:g> sekondes."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%2$d</xliff:g> sekondes."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Jy het die tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd probeer ontsluit. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal hierdie tablet teruggestel word, wat al sy data sal uitvee."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Jy het die foon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd probeer ontsluit. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal hierdie foon teruggestel word, wat al sy data sal uitvee."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Jy het die tablet <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Hierdie tablet sal teruggestel word, wat al sy data sal uitvee."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Jy het die foon <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Hierdie foon sal teruggestel word, wat al sy data sal uitvee."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Jy het die tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd probeer ontsluit. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal hierdie gebruiker verwyder word, wat alle gebruikerdata sal uitvee."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Jy het die foon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd probeer ontsluit. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal hierdie gebruiker verwyder word, wat alle gebruikerdata sal uitvee."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Jy het die tablet <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Die werkprofiel sal verwyder word, wat alle profieldata sal uitvee."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Jy het die foon <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Die werkprofiel sal verwyder word, wat alle profieldata sal uitvee."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou e-posrekening te gebruik om jou tablet te ontsluit.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou e-posrekening te gebruik om jou foon te ontsluit.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Verkeerde SIM-PIN-kode. Jy sal nou jou diensverskaffer moet kontak om jou toestel te ontsluit."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Verkeerde SIM-PIN-kode. Jy het <xliff:g id="NUMBER_1">%d</xliff:g> pogings oor.</item>
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index 855db55..c94ba8b 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ለመክፈት ምናሌ ተጫን።"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"አውታረ መረብ ተቆልፏል"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ምንም ሲም ካርድ የለም"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"በጡባዊ ውስጥ ምንም ሲም ካርድ የለም።"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"በስልክ ውስጥ ምንም ሲም ካርድ የለም።"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"ሲም ካርድ ያስገቡ።"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"ሲም ካርዱ ጠፍቷል ወይም መነበብ አይችልም። እባክዎ ሲም ካርድ ያስገቡ።"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"የማይሰራ ሲም ካርድ።"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"ከ4 እስከ 8 ቁጥሮች የያዘ ፒን ይተይቡ።"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"የPUK ኮድ 8 ወይም ከዚያ በላይ ቁጥሮች ሊኖረው ይገባል።"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"ትክክለኛውን የPUK ኮድ እንደገና ያስገቡ። ተደጋጋሚ ሙከራዎች ሲሙን እስከመጨረሻው ያሰናክሉታል።"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ፒን ኮዶቹ አይገጣጠሙም"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"በጣም ብዙ የስርዓተ ጥለት ሙከራዎች"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"ፒንዎን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ በትክክል አልተየቡም። \n\nበ<xliff:g id="NUMBER_1">%2$d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"የይለፍ ቃልዎን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ተይበዋል።\n\nበ<xliff:g id="NUMBER_1">%2$d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ስለውታል።\n\nበ<xliff:g id="NUMBER_1">%2$d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ጡባዊውን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለማስከፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ይህ ጡባዊ ዳግም ይጀመራል፣ ይህም ሁሉንም ውሂብ ይሰርዛል።"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ስልኩን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለማስከፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ይህ ስልክ ዳግም ይጀመራል፣ ይህም ሁሉንም ውሂብ ይሰርዛል።"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ጡባዊውን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ ሁኔታ ለማስከፈት ሞክረዋል። ስልኩ ዳግም ይጀመራል፣ ይህም ሁሉንም ውሂቡን ይሰርዛል።"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ስልኩን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ ሁኔታ ለማስከፈት ሞክረዋል። ስልኩ ዳግም ይጀመራል፣ ይህም ሁሉንም ውሂቡን ይሰርዛል።"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ጡባዊውን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለማስከፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ይህ ተጠቃሚ ይወገዳል፣ ይህም ሁሉንም የተጠቃሚ ውሂብ ይሰርዛል።"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ስልኩን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለማስከፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ይህ ተጠቃሚ ይወገዳል፣ ይህም ሁሉንም የተጠቃሚ ውሂብ ይሰርዛል።"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ጡባዊውን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለመክፈት ሞክረዋል። የስራ መገለጫው ይወገዳል፣ ይህም ሁሉንም የመገለጫ ውሂብ ይሰርዛል።"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ስልኩን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለመክፈት ሞክረዋል። የስራ መገለጫው ይወገዳል፣ ይህም ሁሉንም የመገለጫ ውሂብ ይሰርዛል።"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊዎን እንዲከፍቱ ይጠየቃሉ።\n\n ከ<xliff:g id="NUMBER_2">%3$d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።\n\nእባክዎ ከ<xliff:g id="NUMBER_2">%3$d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ልክ ያልሆነ የሲም ፒን ኮድ። አሁን መሣሪያዎን ለማስከፈት አገልግሎት አቅራቢዎን ማነጋገር አለብዎት።"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">ልክ ያልሆነ የሲም ፒን ኮድ፣ <xliff:g id="NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል።</item>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index 668957a..fe10afa 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"اضغط على \"القائمة\" لإلغاء التأمين."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"الشبكة مؤمّنة"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ليست هناك شريحة SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ليست هناك شريحة SIM في الجهاز اللوحي."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ليست هناك شريحة SIM في الهاتف."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"أدخل شريحة SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"شريحة SIM مفقودة أو غير قابلة للقراءة. أدخل شريحة SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"شريحة SIM غير قابلة للاستخدام."</string>
@@ -87,17 +85,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"اكتب رمز رقم التعريف الشخصي المكوّن من ٤ إلى ٨ أرقام."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"يجب أن يتضمن رمز PUK ۸ أرقام أو أكثر."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"أعد إدخال رمز PUK الصحيح. وستؤدي المحاولات المتكررة إلى إيقاف شريحة SIM نهائيًا."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"لا يتطابق رمز رقم التعريف الشخصي"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"محاولات النقش كثيرة جدًا"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"لقد كتبت رقم التعريف الشخصي بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانية."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"لقد كتبت كلمة المرور بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانية."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"لقد رسمت نقش فتح القفل بطريقة غير صحيحة <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانية."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"أخطأت في محاولة إلغاء قفل الجهاز اللوحي <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستتم إعادة تعيين هذا الجهاز، ومن ثم يتم حذف جميع بياناته."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"أخطأت في محاولة إلغاء قفل الهاتف <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستتم إعادة تعيين هذا الهاتف، ومن ثم يتم حذف جميع بياناته."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"أخطأت في محاولة إلغاء قفل الجهاز اللوحي <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم إعادة تعيين هذا الجهاز، ومن ثم يتم حذف جميع بياناته."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"أخطأت في محاولة إلغاء قفل الهاتف <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم إعادة تعيين هذا الهاتف، ومن ثم يتم حذف جميع بياناته."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"أخطأت في محاولة إلغاء قفل الجهاز اللوحي <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستتم إزالة هذا المستخدم، ومن ثم يتم حذف جميع بيانات المستخدم."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"أخطأت في محاولة إلغاء قفل الهاتف <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستتم إزالة هذا المستخدم، ومن ثم يتم حذف جميع بيانات المستخدم."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -106,10 +97,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"أخطأت في محاولة إلغاء قفل الجهاز اللوحي <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بياناته."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"أخطأت في محاولة إلغاء قفل الهاتف <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بياناته."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"لقد رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"لقد رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"رمز \"رقم التعريف الشخصي\" لشريحة SIM غير صحيح، ويلزمك الاتصال الآن بمشغّل شبكة الجوّال لإلغاء قفل الجهاز."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="zero">رمز رقم التعريف الشخصي لشريحة SIM غير صحيح، ولم تتبق لديك أي محاولات (<xliff:g id="NUMBER_1">%d</xliff:g>).</item>
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
index 3fef9d7..f814c3a 100644
--- a/packages/SystemUI/res-keyguard/values-as/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"আনলক কৰিবলৈ মেনু টিপক।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"নেটৱর্ক লক কৰা অৱস্থাত আছে"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"কোনো ছিম কাৰ্ড নাই"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"টেবলেটত ছিম কার্ড নাই।"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ফ\'নত ছিম কার্ড নাই।"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"এখন ছিম কাৰ্ড ভৰাওক।"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"ছিম কাৰ্ডখন নাই বা চিনাক্ত কৰিব নোৱাৰি। এখন ছিম কাৰ্ড ভৰাওক।"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"ব্যৱহাৰৰ অযোগ্য ছিম কাৰ্ড।"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"৪টাৰ পৰা ৮টা সংখ্যাযুক্ত এটা পিন লিখক।"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK ক\'ডটো ৮টা বা তাতকৈ অধিক সংখ্যা থকা হ\'ব লাগিব।"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"শুদ্ধ PUK ক\'ডটো পুনৰ দিয়ক। বাৰে বাৰে ভুল ক\'ড দিলে ছিমখন স্থায়ীভাৱে অক্ষম হ\'ব।"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"পিন ক\'ড মিলা নাই"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"বহুতবাৰ ভুলকৈ আর্হি অঁকা হৈছে"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"আপুনি আপোনাৰ পিন <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ লিখিছে। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g>ছেকেণ্ডৰ পিছত আকৌ চেষ্টা কৰক।"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"আপুনি আপোনাৰ পাছৱৰ্ড <xliff:g id="NUMBER_0">%1$d</xliff:g>বাৰ ভুলকৈ লিখিছে। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ছেকেণ্ডৰ পাছত আকৌ চেষ্টা কৰক।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"আপুনি আপোনাৰ আনলক আৰ্হি <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g>ছেকেণ্ডৰ পিছত আকৌ চেষ্টা কৰক।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে টেবলেটটো ৰিছেট কৰা হ\'ব, যি কার্যই টেবলেটটোত থকা সকলো ডেটা মচিব।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে ফ\'নটো ৰিছেট কৰা হ\'ব, যি কার্যই ফ\'নটোত থকা সকলো ডেটা মচিব।"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। এই টেবলেটটো ৰিছেট কৰা হ\'ব, যি কার্যই ইয়াৰ সকলো ডেটা মচিব।"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। এই ফ\'নটো ৰিছেট কৰা হ\'ব, যিয়ে ইয়াৰ সকলো ডেটা মচিব।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে এই ব্যৱহাৰকাৰীক আঁতৰোৱা হ\'ব, যিয়ে ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিব।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে এই ব্যৱহাৰকাৰীক আঁতৰোৱা হ\'ব, যিয়ে ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিব।"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলটো আঁতৰোৱা হ\'ব, যি কার্যই প্ৰ\'ফাইলটোৰ সকলো ডেটা মচিব।"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলটো আঁতৰোৱা হ\'ব, যিয়ে প্ৰ\'ফাইলটোৰ সকলো ডেটা মচিব।"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"আপুনি আপোনাৰ আনলক আৰ্হিটো <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। <xliff:g id="NUMBER_1">%2$d</xliff:g>তকৈ বেছি বাৰ ভুল আৰ্হি আঁকিলে আপোনাৰ টেবলেটটো কোনো একাউণ্টৰ জৰিয়তে আনলক কৰিবলৈ কোৱা হ\'ব।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ছেকেণ্ডৰ পিছত আকৌ চেষ্টা কৰক।"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"আপুনি আপোনাৰ আনলক আৰ্হিটো <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। <xliff:g id="NUMBER_1">%2$d</xliff:g>তকৈ বেছি বাৰ ভুল আৰ্হি আঁকিলে আপোনাৰ ফ\'নটো কোনো একাউণ্টৰ জৰিয়তে আনলক কৰিবলৈ কোৱা হ\'ব।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ছেকেণ্ডৰ পিছত আকৌ চেষ্টা কৰক।"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ছিমৰ ভুল পিন ক\'ড, আপোনাৰ ডিভাইচটো আনলক কৰিবলৈ আপুনি এতিয়া আপোনাৰ বাহকৰ সৈতে যোগাযোগ কৰিবই লাগিব।"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">ছিমৰ ভুল পিন ক’ড, আপুনি আৰু <xliff:g id="NUMBER_1">%d</xliff:g> বাৰ প্ৰয়াস কৰিব পাৰিব।</item>
diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml
index 8bc953e..e04f305 100644
--- a/packages/SystemUI/res-keyguard/values-az/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-az/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Kilidi açmaq üçün Menyu düyməsinə basın."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Şəbəkə kilidlidir"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM kart yoxdur."</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Planşetdə SIM kart yoxdur."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefonda SIM kart yoxdur."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM kart daxil edin."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM kart yoxdur və ya oxuna bilinmir. SIM kart daxil edin."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Yararsız SIM kart."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4-8 rəqəmli PIN daxil edin."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kod 8 rəqəm və ya daha çox olmalıdır."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Yenidən düzgün PUK kod daxil edin. Təkrarlanan cəhdlər SIM-i birdəfəlik sıradan çıxaracaq."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodlar uyğun gəlmir"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Həddindən çox model cəhdi"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN kodu <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış daxil etdiniz. \n \n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Parolu <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış daxil etdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Kilid modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Planşetin kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış cəhdlər etmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra bu planşet sıfırlanacaq və bütün data silinəcək."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış cəhdlər etmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra bu telefon sıfırlanacaq və bütün data silinəcək."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Planşetin kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhdlər etmisiniz. Bu planşet sıfırlanacaq və bütün data silinəcək."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhdlər etmisiniz. Bu telefon sıfırlanacaq və bütün data silinəcək."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Planşetin kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra bu istifadəçi silinəcək və bütün istifadəçi datası ləğv ediləcək."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra bu istifadəçi silinəcək və bütün istifadəçi datası ləğv ediləcək."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Planşetin kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhdlər etmisiniz. İş profili silinəcək və bütün data ləğv ediləcək."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhdlər etmisiniz. İş profili silinəcək və bütün data ləğv ediləcək."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Kilid açma modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra planşet kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Kilid açma modelini artıq <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra telefon kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Yanlış SIM PIN kodu cihazın açılması üçün operatorla indi əlaqə saxlamalısınız."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Yanlış SIM PIN kodu, <xliff:g id="NUMBER_1">%d</xliff:g> cəhdiniz qalır.</item>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index 116e096..82dca6b 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite Meni da biste otključali."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nema SIM kartice"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"U tabletu nema SIM kartice."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"U telefonu nema SIM kartice."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Umetnite SIM karticu."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM kartica nedostaje ili ne može da se pročita. Umetnite SIM karticu."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM kartica je neupotrebljiva."</string>
@@ -84,17 +82,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Unesite PIN koji ima 4–8 brojeva."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kôd treba da ima 8 ili više brojeva."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Ponovo unesite tačan PUK kôd. Ponovljeni pokušaji će trajno onemogućiti SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodovi se ne podudaraju"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Previše pokušaja unosa šablona"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Uneli ste pogrešan PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Uneli ste pogrešnu lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Nacrtali ste netačan šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, ovaj tablet će se resetovati, čime se brišu svi podaci korisnika."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, ovaj telefon će se resetovati, čime se brišu svi podaci korisnika."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Ovaj tablet će se resetovati, čime se brišu svi podaci."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Ovaj telefon će se resetovati, čime se brišu svi podaci."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -103,10 +94,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo profil za Work, čime se brišu svi podaci sa profila."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo profil za Work, čime se brišu svi podaci sa profila."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, zatražićemo da otključate tablet pomoću imejl naloga.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, zatražićemo da otključate telefon pomoću imejl naloga.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Netačan PIN kôd za SIM. Sada morate da kontaktirate mobilnog operatera da biste otključali uređaj."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Netačan PIN kôd za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj.</item>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index 5bb89ae..d9a4508 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Націсніце кнопку \"Меню\", каб разблакіраваць."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Сетка заблакіравана"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Няма SIM-карты"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"У планшэце няма SIM-карты."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"У тэлефоне няма SIM-карты."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Устаўце SIM-карту."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM-карта адсутнічае ці не чытаецца. Устаўце SIM-карту."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM-карту немагчыма выкарыстоўваць."</string>
@@ -85,17 +83,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Увядзіце PIN-код, які змяшчае ад 4 да 8 лічбаў."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-код павінен утрымліваць 8 лічбаў ці больш."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Паўторна ўвядзіце правільны PUK-код. Паўторныя спробы прывядуць да адключэння SIM-карты назаўсёды."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-коды не супадаюць"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Занадта шмат спроб уводу ўзору"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Вы няправільна ўвялі PIN-код столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nПаўтарыце спробу праз <xliff:g id="NUMBER_1">%2$d</xliff:g> с."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Вы няправільна ўвялі пароль столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nПаўтарыце спробу праз <xliff:g id="NUMBER_1">%2$d</xliff:g> с."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Вы няправільна ўвялі ўзор разблакіроўкі столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nПаўтарыце спробу праз <xliff:g id="NUMBER_1">%2$d</xliff:g> с."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Вы не змаглі разблакіраваць планшэт столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) ён будзе скінуты да заводскіх налад, гэта прывядзе да выдалення ўсіх даных."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Вы не змаглі разблакіраваць тэлефон столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) ён будзе скінуты да заводскіх налад, гэта прывядзе да выдалення ўсіх даных."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Вы не змаглі разблакіраваць планшэт столькі разоў: <xliff:g id="NUMBER">%d</xliff:g>. Цяпер ён будзе скінуты да заводскіх налад, гэта прывядзе да выдалення ўсіх даных."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Вы не змаглі разблакіраваць тэлефон столькі разоў: <xliff:g id="NUMBER">%d</xliff:g>. Цяпер ён будзе скінуты да заводскіх налад, гэта прывядзе да выдалення ўсіх даных."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Вы не змаглі разблакіраваць планшэт столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) гэты карыстальнік будзе выдалены, гэта прывядзе да выдалення ўсіх карыстальніцкіх даных."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Вы не змаглі разблакіраваць тэлефон столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) гэты карыстальнік будзе выдалены, гэта прывядзе да выдалення ўсіх карыстальніцкіх даных."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -104,10 +95,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Вы не змаглі разблакіраваць планшэт столькі разоў: <xliff:g id="NUMBER">%d</xliff:g>. Працоўны профіль будзе выдалены, гэта прывядзе да выдалення ўсіх даных у профілі."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Вы не змаглі разблакіраваць тэлефон столькі разоў: <xliff:g id="NUMBER">%d</xliff:g>. Працоўны профіль будзе выдалены, гэта прывядзе да выдалення ўсіх даных у профілі."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Вы няправільна ўвялі ўзор разблакіроўкі столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) вам будзе прапанавана разблакіраваць планшэт, увайшоўшы ва ўліковы запіс электроннай пошты.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Вы няправільна ўвялі ўзор разблакіроўкі столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) вам будзе прапанавана разблакіраваць тэлефон, увайшоўшы ва ўліковы запіс электроннай пошты.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Няправільны PIN-код SIM-карты, цяпер вы павінны звязацца з аператарам для разблакіроўкі прылады."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Няправільны PIN-код SIM-карты, у вас засталася <xliff:g id="NUMBER_1">%d</xliff:g> спроба.</item>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index 2b37c52..3b68a42 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Натиснете „Меню“, за да отключите."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежата е заключена"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Няма SIM карта"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"В таблета няма SIM карта."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"В телефона няма SIM карта."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Поставете SIM карта."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM картата липсва или е нечетлива. Поставете SIM карта."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Неизползваема SIM карта."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Въведете ПИН код с четири до осем цифри."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK кодът трябва да е с осем или повече цифри."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Въведете отново правилния PUK код. Многократните опити ще деактивират за постоянно SIM картата."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ПИН кодовете не съвпадат"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Опитите за фигурата са твърде много"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Въведохте неправилно ПИН кода си <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Въведохте неправилно паролата си <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Опитахте да отключите таблета и сбъркахте <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита той ще бъде нулиран, при което ще се изтрият всичките му данни."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Опитахте да отключите телефона и сбъркахте <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита той ще бъде нулиран, при което ще се изтрият всичките му данни."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Опитахте да отключите таблета и сбъркахте <xliff:g id="NUMBER">%d</xliff:g> пъти. Той ще бъде нулиран, при което ще се изтрият всичките му данни."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Опитахте да отключите телефона и сбъркахте <xliff:g id="NUMBER">%d</xliff:g> пъти. Той ще бъде нулиран, при което ще се изтрият всичките му данни."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Опитахте да отключите таблета и сбъркахте <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита този потребител ще бъде премахнат, при което ще се изтрият всички данни за него."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Опитахте да отключите телефона и сбъркахте <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита този потребител ще бъде премахнат, при което ще се изтрият всички данни за него."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Опитахте да отключите таблета и сбъркахте <xliff:g id="NUMBER">%d</xliff:g> пъти. Служебният потребителски профил ще бъде премахнат, при което ще се изтрият всички данни за него."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Опитахте да отключите телефона и сбъркахте <xliff:g id="NUMBER">%d</xliff:g> пъти. Служебният потребителски профил ще бъде премахнат, при което ще се изтрият всички данни за него."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета си посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Неправилен ПИН код за SIM картата – сега трябва да се свържете с оператора си, за да отключите устройството."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Неправилен ПИН код за SIM картата – остават ви <xliff:g id="NUMBER_1">%d</xliff:g> опита.</item>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index 26881d8..7d0d4b9 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"আনলক করতে মেনুতে টিপুন।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"নেটওয়ার্ক লক করা আছে"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"কোনো সিম কার্ড নেই"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ট্যাবলেটের মধ্যে কোনো সিম কার্ড নেই।"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ফোনের মধ্যে কোনো সিম কার্ড নেই।"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"একটি সিম কার্ড লাগান।"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"সিম কার্ড নেই বা সেটি পড়া যাচ্ছে না। একটি সিম কার্ড লাগান।"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"অব্যবহারযোগ্য সিম কার্ড।"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"একটি ৪ থেকে ৮ সংখ্যার পিন লিখুন।"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK কোডটি ৮ বা তার বেশি সংখ্যার হতে হবে।"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"সঠিক PUK কোডটি পুনরায় লিখুন। বার বার চেষ্টা করা হলে সিমটি স্থায়ীভাবে অক্ষম হয়ে যাবে।"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"পিন কোডগুলি মিলছে না"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"বিভিন্ন প্যাটার্নের সাহায্যে খুব বেশি বার প্রচেষ্টা করা হয়ে গেছে"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"আপনি আপনার পিন টাইপ করতে <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করেছেন৷ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আপনার পাসওয়ার্ড লিখেছেন।\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আপনার আনলকের প্যাটার্ন এঁকেছেন।\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ট্যাবলেটটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ফোনটি আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ফোনটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুলভাবে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন। এই ফোনটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুলভাবে ফোনটি আনলক করার চেষ্টা করেছেন। এই ফোনটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ব্যবহারকারীকে সরিয়ে দেওয়া হবে, যার ফলে ব্যবহারকারীর সমস্ত ডেটা মুছে যাবে।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ফোনটি আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ব্যবহারকারীকে সরিয়ে দেওয়া হবে, যার ফলে ব্যবহারকারীর সমস্ত ডেটা মুছে যাবে।"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুলভাবে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন। কাজের প্রোফাইলটি সরিয়ে দেওয়া হবে, যার ফলে প্রোফাইলের সমস্ত ডেটা মুছে যাবে।"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুলভাবে ফোনটি আনলক করার চেষ্টা করেছেন। কাজের প্রোফাইলটি সরিয়ে দেওয়া হবে, যার ফলে প্রোফাইলের সমস্ত ডেটা মুছে যাবে।"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আনলকের প্যাটার্ন এঁকেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর আপনাকে একটি ইমেল অ্যাকাউন্টের মাধ্যমে আপনার ট্যাবলেটটি আনলক করতে বলা হবে।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আনলকের প্যাটার্ন এঁকেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর আপনাকে একটি ইমেল অ্যাকাউন্টের মাধ্যমে আপনার ফোনটি আনলক করতে বলা হবে।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ভুল সিম পিন কোড দিয়েছেন, আপনার ডিভাইসটি আনলক করতে এখন আপনাকে অবশ্যই আপনার পরিষেবা প্রদানকারীর সাথে যোগাযোগ করতে হবে।"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">সিমের পিন কোডটি ভুল, আপনি আর <xliff:g id="NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারেন।</item>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 9e36a72..99140ce 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite meni da otključate."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nema SIM kartice"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nema SIM kartice u tabletu."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Nema SIM kartice u telefonu."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Umetnite SIM karticu."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM kartica nije umetnuta ili je uređaj ne može očitati. Umetnite SIM karticu."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Neupotrebljiva SIM kartica."</string>
@@ -84,17 +82,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Unesite PIN koji sadrži 4 do 8 brojeva."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kôd treba sadržavati najmanje 8 brojeva."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Ponovo unesite ispravan PUK kôd. Ponovljeni pokušaji će trajno onemogućiti SIM karticu."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-ovi se ne poklapaju"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Previše puta ste pokušali otključati uređaj crtanjem uzorka"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Pogrešno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Pogrešno ste unijeli lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Pogrešno ste nacrtali svoj uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati tablet. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, tablet će se vratiti na fabričke postavke i svi podaci će se izbrisati."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati telefon. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, telefon će se vratiti na fabričke postavke i svi podaci će se izbrisati."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati tablet. Tablet će se sada vratiti na fabričke postavke i svi podaci će se izbrisati."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati telefon. Telefon će se sada vratiti na fabričke postavke i svi podaci će se izbrisati."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati tablet. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, ovaj korisnik će se ukloniti i svi podaci korisnika će se izbrisati."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati telefon. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, ovaj korisnik će se ukloniti i svi podaci korisnika će se izbrisati."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -103,10 +94,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati tablet. Poslovni profil će se ukloniti i svi podaci s profila će se izbrisati."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati telefon. Poslovni profil će se ukloniti i svi podaci s profila će se izbrisati."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da tablet otključate koristeći račun e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da telefon otključate koristeći račun e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"PIN za SIM karticu je netačan. Za otključavanje uređaja sada se morate obratiti svom operateru."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">PIN za SIM karticu je netačan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 8059ec3..7bb3677 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Prem Menú per desbloquejar."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"La xarxa està bloquejada"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No hi ha cap SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No hi ha cap SIM a la tauleta."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No hi ha cap SIM al telèfon."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insereix una targeta SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Falta la targeta SIM o no es pot llegir. Insereix-ne una."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"La targeta SIM no es pot fer servir."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Escriu un PIN que tingui entre 4 i 8 números."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"El codi PUK ha de tenir 8 números o més."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Torna a introduir el codi PUK correcte. Si ho intentes diverses vegades, es desactivarà la SIM permanentment."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Els codis PIN no coincideixen"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Has intentat dibuixar el patró massa vegades"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Has escrit el PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Has escrit la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, la tauleta es restablirà i se\'n suprimiran totes les dades."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, el telèfon es restablirà i se\'n suprimiran totes les dades."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. La tauleta es restablirà i se\'n suprimiran totes les dades."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. El telèfon es restablirà i se\'n suprimiran totes les dades."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, l\'usuari se suprimirà, juntament amb totes les seves dades."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, l\'usuari se suprimirà, juntament amb totes les seves dades."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. El perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. El perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"El codi PIN de la SIM no és correcte. Contacta amb l\'operador de telefonia mòbil per desbloquejar el dispositiu."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">El codi PIN de la SIM no és correcte. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents.</item>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index b8bfe07..7e430d6 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Klávesy odemknete stisknutím tlačítka nabídky."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Síť je blokována"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Chybí SIM karta"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"V tabletu není SIM karta."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"V telefonu není SIM karta."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Vložte SIM kartu."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM karta chybí nebo je nečitelná. Vložte SIM kartu."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Nepoužitelná SIM karta."</string>
@@ -85,17 +83,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Zadejte kód PIN o délce 4–8 číslic."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Minimální délka kódu PUK je 8 číslic."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Znovu zadejte správný kód PUK. Opakovanými pokusy SIM kartu trvale zablokujete."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kódy PIN se neshodují"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Příliš mnoho pokusů o zadání gesta"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste zadali nesprávný kód PIN. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali heslo. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste zadali nesprávné bezpečnostní gesto. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Již jste se <xliff:g id="NUMBER_0">%1$d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech bude tablet resetován, čímž se z něj smažou všechna data."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Již jste se <xliff:g id="NUMBER_0">%1$d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech bude telefon resetován, čímž se z něj smažou všechna data."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Tablet bude resetován, čímž z něj budou smazána všechna data."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Telefon bude resetován, čímž z něj budou smazána všechna data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Již jste se <xliff:g id="NUMBER_0">%1$d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech bude tento uživatel odstraněn, čímž se smažou všechna jeho data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Již jste se <xliff:g id="NUMBER_0">%1$d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech bude tento uživatel odstraněn, čímž se smažou všechna jeho data."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -104,10 +95,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Pracovní profil bude odstraněn, čímž budou smazána všechna jeho data."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Pracovní profil bude odstraněn, čímž budou smazána všechna jeho data."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali své bezpečnostní gesto. Po <xliff:g id="NUMBER_1">%2$d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali své bezpečnostní gesto. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Zadali jste nesprávný kód PIN SIM karty. Nyní musíte za účelem odemknutí zařízení kontaktovat svého operátora."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="few">Zadali jste nesprávný kód PIN SIM karty. Máte ještě <xliff:g id="NUMBER_1">%d</xliff:g> pokusy.</item>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index f134734..a66f02b 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tryk på menuen for at låse op."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Netværket er låst"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Intet SIM-kort"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Der er ikke noget SIM-kort i denne tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Der er ikke noget SIM-kort i telefonen."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Indsæt et SIM-kort."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM-kortet mangler eller kan ikke læses. Indsæt et SIM-kort."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Ubrugeligt SIM-kort."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Angiv en pinkode på mellem 4 og 8 tal."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-koden skal være på 8 tal eller mere."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Angiv den korrekte PUK-kode. Gentagne forsøg deaktiverer permanent SIM-kortet."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Pinkoderne stemmer ikke overens"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Du har brugt for mange forsøg på at tegne mønsteret korrekt"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Du har indtastet en forkert pinkode <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Du har forsøgt at låse denne tablet op med den forkerte adgangskode <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg nulstilles denne tablet, hvilket sletter alle dens data."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Du har forsøgt at låse telefonen op med den forkerte adgangskode <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg nulstilles denne telefon, hvilket sletter alle dens data."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Du har forsøgt at låse denne tablet op på forkert vis <xliff:g id="NUMBER">%d</xliff:g> gange. Denne tablet nulstilles, hvilket sletter alle dens data."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Du har forsøgt at låse telefonen op på forkert vis <xliff:g id="NUMBER">%d</xliff:g> gange. Telefonen nulstilles, hvilket sletter alle dens data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Du har forsøgt at låse denne tablet op med den forkerte adgangskode <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg fjernes denne bruger, hvilket sletter alle brugerdata."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Du har forsøgt at låse telefonen op med den forkerte adgangskode <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg fjernes denne bruger, hvilket sletter alle brugerdata."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Du har forsøgt at låse denne tablet op på forkert vis <xliff:g id="NUMBER">%d</xliff:g> gange. Arbejdsprofilen fjernes, hvilket sletter alle profildata."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Du har forsøgt at låse telefonen op på forkert vis <xliff:g id="NUMBER">%d</xliff:g> gange. Arbejdsprofilen fjernes, hvilket sletter alle profildata."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg bliver du bedt om at låse din tablet op ved hjælp af en mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg bliver du bedt om at låse din telefon op ved hjælp af en mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Forkert pinkode til SIM-kort. Du er nu nødt til at kontakte dit mobilselskab for at låse din enhed op."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Forkert pinkode til SIM-kort. Du har <xliff:g id="NUMBER_1">%d</xliff:g> forsøg tilbage.</item>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index abc43da..7c0839a 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Zum Entsperren die Menütaste drücken."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Netzwerk gesperrt"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Keine SIM-Karte"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Keine SIM-Karte im Tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Keine SIM-Karte im Telefon."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM-Karte einlegen."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM-Karte fehlt oder ist nicht lesbar. Bitte lege eine SIM-Karte ein."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM-Karte unbrauchbar."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Gib eine 4- bis 8-stellige PIN ein."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Der PUK-Code muss mindestens 8 Ziffern aufweisen."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Gib den richtigen PUK-Code ein. Bei wiederholten Versuchen wird die SIM-Karte dauerhaft deaktiviert."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-Codes stimmen nicht überein"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Zu viele Musterversuche"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Du hast deine PIN <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nBitte versuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden noch einmal."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Du hast dein Passwort <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nBitte versuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden noch einmal."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. \n\nBitte versuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden noch einmal."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieses Tablet zurückgesetzt. Dadurch werden alle Gerätedaten gelöscht."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieses Telefon zurückgesetzt. Dadurch werden alle Gerätedaten gelöscht."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Dieses Tablet wird nun zurückgesetzt und alle Gerätedaten werden gelöscht."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Dieses Telefon wird nun zurückgesetzt und alle Gerätedaten werden gelöscht."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieser Nutzer entfernt. Dadurch werden alle Nutzerdaten gelöscht."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieser Nutzer entfernt. Dadurch werden alle Nutzerdaten gelöscht."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Arbeitsprofil wird nun entfernt und alle Profildaten werden gelöscht."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Das Arbeitsprofil wird nun entfernt und alle Profildaten werden gelöscht."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Tablet mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Telefon mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Falscher PIN-Code der SIM-Karte. Bitte wende dich an deinen Mobilfunkanbieter, damit er dein Gerät entsperrt."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Falscher PIN-Code der SIM-Karte. Du hast noch <xliff:g id="NUMBER_1">%d</xliff:g> Versuche.</item>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index 042a831..e9bd207 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Πατήστε \"Μενού\" για ξεκλείδωμα."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Κλειδωμένο δίκτυο"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Δεν υπάρχει κάρτα SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Δεν υπάρχει κάρτα SIM στο tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Δεν υπάρχει κάρτα SIM στο τηλέφωνο."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Τοποθετήστε μια κάρτα SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Η κάρτα SIM δεν υπάρχει ή δεν είναι δυνατή η ανάγνωσή της. Τοποθετήστε μια κάρτα SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Η κάρτα SIM δεν μπορεί να χρησιμοποιηθεί."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Πληκτρολογήστε έναν αριθμό PIN που να αποτελείται από 4 έως 8 αριθμούς."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Ο κωδικός PUK θα πρέπει να περιέχει τουλάχιστον 8 αριθμούς."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Εισαγάγετε ξανά τον κωδικό PUK. Οι επαναλαμβανόμενες προσπάθειες θα απενεργοποιήσουν οριστικά την κάρτα SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Δεν υπάρχει αντιστοιχία μεταξύ των κωδικών PIN"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Πάρα πολλές προσπάθειες μοτίβου!"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Έχετε πληκτρολογήσει τον αριθμό PIN εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%2$d</xliff:g> δευτερόλεπτα."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%2$d</xliff:g> δευτερόλεπτα."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Σχεδιάσατε εσφαλμένα το μοτίβο ξεκλειδώματος<xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%2$d</xliff:g> δευτερόλεπτα."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Δοκιμάσατε να ξεκλειδώσετε το tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές χωρίς επιτυχία. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, αυτό το tablet θα ρυθμιστεί εκ νέου και θα διαγραφούν όλα τα δεδομένα του."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Δοκιμάσατε να ξεκλειδώσετε το τηλέφωνο <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές χωρίς επιτυχία. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, αυτό το τηλέφωνο θα ρυθμιστεί εκ νέου και θα διαγραφούν όλα τα δεδομένα του."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Δοκιμάσατε να ξεκλειδώσετε αυτό το tablet <xliff:g id="NUMBER">%d</xliff:g> φορές χωρίς επιτυχία. Αυτό το tablet θα ρυθμιστεί εκ νέου και θα διαγραφούν όλα τα δεδομένα του."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Δοκιμάσατε να ξεκλειδώσετε το τηλέφωνο <xliff:g id="NUMBER">%d</xliff:g> φορές χωρίς επιτυχία. Αυτό το τηλέφωνο θα ρυθμιστεί εκ νέου και θα διαγραφούν όλα τα δεδομένα του."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Δοκιμάσατε να ξεκλειδώσετε το tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές χωρίς επιτυχία. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, αυτός ο χρήστης θα καταργηθεί και θα διαγραφούν όλα τα δεδομένα χρήστη."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Δοκιμάσατε να ξεκλειδώσετε το τηλέφωνο <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές χωρίς επιτυχία. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, αυτός ο χρήστης θα καταργηθεί και θα διαγραφούν όλα τα δεδομένα χρήστη."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Δοκιμάσατε να ξεκλειδώσετε το tablet <xliff:g id="NUMBER">%d</xliff:g> φορές χωρίς επιτυχία. Το προφίλ εργασίας θα καταργηθεί και θα διαγραφούν όλα τα δεδομένα προφίλ."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Δοκιμάσατε να ξεκλειδώσετε το τηλέφωνο <xliff:g id="NUMBER">%d</xliff:g> φορές χωρίς επιτυχία. Το προφίλ εργασίας θα καταργηθεί και θα διαγραφούν όλα τα δεδομένα προφίλ."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, θα σας ζητηθεί να ξεκλειδώσετε το tablet με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%3$d</xliff:g> δευτερόλεπτα."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%3$d</xliff:g> δευτερόλεπτα."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Λανθασμένος κωδικός PIN κάρτας SIM. Θα πρέπει να επικοινωνήσετε με την εταιρεία κινητής τηλεφωνίας σας για να ξεκλειδώσετε τη συσκευή σας."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Λανθασμένος κωδικός PIN κάρτας SIM. Απομένουν άλλες <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες.</item>
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index 6d95c6a..969a8d6 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No SIM card in tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No SIM card in phone."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insert a SIM card."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"The SIM card is missing or not readable. Insert a SIM card."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Unusable SIM card."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Type a PIN that is 4 to 8 numbers."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK code should be 8 numbers or more."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN codes do not match"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Too many pattern attempts"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Incorrect SIM PIN code; you must now contact your operator to unlock your device."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Incorrect SIM PIN code. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
diff --git a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
index d594cd0..fcc0887 100644
--- a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No SIM card in tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No SIM card in phone."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insert a SIM card."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"The SIM card is missing or not readable. Insert a SIM card."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Unusable SIM card."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Type a PIN that is 4 to 8 numbers."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK code should be 8 numbers or more."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN codes do not match"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Too many pattern attempts"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Incorrect SIM PIN code; you must now contact your operator to unlock your device."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Incorrect SIM PIN code. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index 6d95c6a..969a8d6 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No SIM card in tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No SIM card in phone."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insert a SIM card."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"The SIM card is missing or not readable. Insert a SIM card."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Unusable SIM card."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Type a PIN that is 4 to 8 numbers."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK code should be 8 numbers or more."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN codes do not match"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Too many pattern attempts"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Incorrect SIM PIN code; you must now contact your operator to unlock your device."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Incorrect SIM PIN code. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index 6d95c6a..969a8d6 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No SIM card in tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No SIM card in phone."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insert a SIM card."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"The SIM card is missing or not readable. Insert a SIM card."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Unusable SIM card."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Type a PIN that is 4 to 8 numbers."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK code should be 8 numbers or more."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN codes do not match"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Too many pattern attempts"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Incorrect SIM PIN code; you must now contact your operator to unlock your device."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Incorrect SIM PIN code. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
index b8a6f10..975b1f6 100644
--- a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Network locked"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"No SIM card"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No SIM card in tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No SIM card in phone."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insert a SIM card."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"The SIM card is missing or not readable. Insert a SIM card."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Unusable SIM card."</string>
@@ -83,25 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Type a PIN that is 4 to 8 numbers."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK code should be 8 numbers or more."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN codes does not match"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Too many pattern attempts"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
- <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="9046628517316763961">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This user will be removed, which will delete all user data."</string>
- <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3588779327358321092">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This user will be removed, which will delete all user data."</string>
- <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="6114158710353725041">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="8345451368768804892">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Incorrect SIM PIN code you must now contact your carrier to unlock your device."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Incorrect SIM PIN code, you have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index 411f855..80df3be 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Presiona Menú para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada para la red"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sin tarjeta SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No hay tarjeta SIM en la tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No hay tarjeta SIM en el teléfono."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Inserta una tarjeta SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Falta la tarjeta SIM o no se puede leer. Introduce una tarjeta SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Tarjeta SIM inutilizable"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Escribe un PIN que tenga entre 4 y 8 números."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"El código PUK debe tener al menos 8 números."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Vuelve a ingresar el código PUK correcto. Si ingresas un código incorrecto varias veces, se inhabilitará la tarjeta SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Los códigos PIN no coinciden"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Demasiados intentos incorrectos para el ingreso del patrón"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Escribiste tu PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Escribiste tu contraseña <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Dibujaste tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Intentaste desbloquear la tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se restablecerá la tablet, lo que borrará todos los datos."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se restablecerá el teléfono, lo que borrará todos los datos."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Intentaste desbloquear la tablet <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se restablecerá la tablet, lo que borrará todos los datos."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se restablecerá el teléfono, lo que borrará todos los datos."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Intentaste desbloquear la tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se quitará este usuario, lo que borrará todos los datos asociados."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se quitará este usuario, lo que borrará todos los datos asociados."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Intentaste desbloquear la tablet <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se quitará el perfil de trabajo, lo que borrará todos los datos asociados."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se quitará el perfil de trabajo, lo que borrará todos los datos asociados."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu tablet mediante una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"El código PIN de la tarjeta SIM es incorrecto. Debes comunicarte con tu proveedor para desbloquear el dispositivo."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">El código PIN de la tarjeta SIM es incorrecto. Te quedan <xliff:g id="NUMBER_1">%d</xliff:g> intentos más.</item>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index 4430046..abfaf3a 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pulsa el menú para desbloquear la pantalla."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada para la red"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Falta la tarjeta SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No se ha insertado ninguna tarjeta SIM en el tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No se ha insertado ninguna tarjeta SIM en el teléfono."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Inserta una tarjeta SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Falta la tarjeta SIM o no se puede leer. Inserta una tarjeta SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"La tarjeta SIM se ha inhabilitado."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Escribe un código PIN que tenga entre 4 y 8 dígitos."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"El código PUK debe tener 8 números como mínimo."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Vuelve a introducir el código PUK correcto. Si introduces un código incorrecto varias veces, se inhabilitará la tarjeta SIM de forma permanente."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Los códigos PIN no coinciden"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Has fallado demasiadas veces al introducir el patrón"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al escribir el PIN. \n\nVuelve a intentarlo dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al introducir la contraseña. \n\nVuelve a intentarlo dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar el patrón de desbloqueo. \n\nVuelve a intentarlo dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al desbloquear el tablet. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, se recuperarán los ajustes de fábrica de este tablet y se eliminarán todos sus datos."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al desbloquear el teléfono. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, se recuperarán los ajustes de fábrica de este teléfono y se eliminarán todos sus datos."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Has fallado <xliff:g id="NUMBER">%d</xliff:g> veces al desbloquear el tablet. Se recuperarán los ajustes de fábrica de este tablet y se eliminarán todos sus datos."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Has fallado <xliff:g id="NUMBER">%d</xliff:g> veces al desbloquear el teléfono. Se recuperarán los ajustes de fábrica de este teléfono y se eliminarán todos sus datos."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al desbloquear el tablet. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, se quitará a este usuario y se eliminarán todos sus datos."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al desbloquear el teléfono. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, se quitará a este usuario y se eliminarán todos sus datos."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Has fallado <xliff:g id="NUMBER">%d</xliff:g> veces al desbloquear el tablet. Se quitará este perfil de trabajo se quitará y se eliminarán todos sus datos."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Has fallado <xliff:g id="NUMBER">%d</xliff:g> veces al desbloquear el teléfono. Se quitará este perfil de trabajo y se eliminarán todos sus datos."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, tendrás que usar una cuenta de correo electrónico para desbloquear el tablet.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, tendrás que usar una cuenta de correo electrónico para desbloquear el teléfono.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"El código PIN de la tarjeta SIM es incorrecto. Debes ponerte en contacto con tu operador para desbloquear el dispositivo."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">El código PIN de la tarjeta SIM es incorrecto. Quedan <xliff:g id="NUMBER_1">%d</xliff:g> intentos.</item>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index 888a57f..bf8d067 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Vajutage avamiseks menüüklahvi."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Võrk on lukus"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM-kaarti pole"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Tahvelarvutis pole SIM-kaarti."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefonis pole SIM-kaarti."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Sisestage SIM-kaart."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM-kaart puudub või on loetamatu. Sisestage SIM-kaart."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Kasutamiskõlbmatu SIM-kaart."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Sisestage 4–8-numbriline PIN-kood."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-koodi pikkus peab olema vähemalt kaheksa numbrit."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Sisestage uuesti õige PUK-kood. Korduvkatsete korral keelatakse SIM-kaart jäädavalt."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-koodid ei ole vastavuses"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Liiga palju mustrikatseid"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Olete PIN-koodi <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti sisestanud. \n\nProovige <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundi pärast uuesti."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Olete parooli <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti sisestanud. \n\nProovige <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundi pärast uuesti."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Olete oma avamismustrit <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti joonistanud. \n\nProovige <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundi pärast uuesti."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Olete püüdnud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset tahvelarvuti lähtestatakse ja kõik selle andmed kustutatakse."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Olete püüdnud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset telefon lähtestatakse ja kõik selle andmed kustutatakse."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Olete püüdnud <xliff:g id="NUMBER">%d</xliff:g> korda tahvelarvutit valesti avada. Tahvelarvuti lähtestatakse ja kõik selle andmed kustutatakse."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Olete püüdnud <xliff:g id="NUMBER">%d</xliff:g> korda telefoni valesti avada. Telefon lähtestatakse ja kõik selle andmed kustutatakse."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Olete püüdnud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset kasutaja eemaldatakse ja kõik kasutajaandmed kustutatakse."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Olete püüdnud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset kasutaja eemaldatakse ja kõik kasutajaandmed kustutatakse."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Olete püüdnud <xliff:g id="NUMBER">%d</xliff:g> korda tahvelarvutit valesti avada. Tööprofiil eemaldatakse ja kõik profiiliandmed kustutatakse."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Olete püüdnud <xliff:g id="NUMBER">%d</xliff:g> korda telefoni valesti avada. Tööprofiil eemaldatakse ja kõik profiiliandmed kustutatakse."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM-kaardi vale PIN-kood. Seadme avamiseks peate nüüd ühendust võtma oma operaatoriga."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM-kaardi vale PIN-kood. Teil on jäänud veel <xliff:g id="NUMBER_1">%d</xliff:g> katset.</item>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 117305f..6cf00d8 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Desblokeatzeko, sakatu Menua."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Sarea blokeatuta dago"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ez dago SIM txartelik"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Ez dago SIM txartelik tabletan."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Ez dago SIM txartelik telefonoan."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Sartu SIM txartela."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM txartela falta da edo ezin da irakurri. Sartu SIM txartel bat."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM txartela erabilgaitza da."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Idatzi 4 eta 8 zenbaki bitarteko PIN bat."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kodeak 8 zenbaki izan behar ditu gutxienez."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Idatzi berriro PUK kode zuzena. Hainbat saiakera oker eginez gero, betiko desgaituko da SIM txartela."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodeak ez datoz bat"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Eredua marrazteko saiakera gehiegi egin dira"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz idatzi duzu PIN kodea, baina huts egin duzu denetan. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%2$d</xliff:g> segundo barru."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz idatzi duzu pasahitza, baina huts egin duzu denetan. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%2$d</xliff:g> segundo barru."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz marraztu duzu desblokeatzeko eredua, baina huts egin duzu denetan. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%2$d</xliff:g> segundo barru."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz saiatu zara tableta desblokeatzen, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, berrezarri egingo da tableta eta, ondorioz, bertako datu guztiak ezabatuko dira."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz saiatu zara telefonoa desblokeatzen, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, berrezarri egingo da telefonoa eta, ondorioz, bertako datu guztiak ezabatuko dira."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"<xliff:g id="NUMBER">%d</xliff:g> aldiz saiatu zara tableta desblokeatzen, baina huts egin duzu denetan. Tableta berrezarri egingo da eta, ondorioz, bertako datu guztiak ezabatuko dira."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"<xliff:g id="NUMBER">%d</xliff:g> aldiz saiatu zara telefonoa desblokeatzen, baina huts egin duzu denetan. Telefonoa berrezarri egingo da eta, ondorioz, bertako datu guztiak ezabatuko dira."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz saiatu zara tableta desblokeatzen, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, kendu egingo da erabiltzailea eta, ondorioz, haren datu guztiak ezabatuko dira."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz saiatu zara telefonoa desblokeatzen, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, kendu egingo da erabiltzailea eta, ondorioz, haren datu guztiak ezabatuko dira."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"<xliff:g id="NUMBER">%d</xliff:g> aldiz saiatu zara tableta desblokeatzen, baina huts egin duzu denetan. Laneko profila kendu egingo da eta, ondorioz, profileko datu guztiak ezabatuko dira."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"<xliff:g id="NUMBER">%d</xliff:g> aldiz saiatu zara telefonoa desblokeatzen, baina huts egin duzu denetan. Laneko profila kendu egingo da eta, ondorioz, profileko datu guztiak ezabatuko dira."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz marraztu duzu desblokeatzeko eredua, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, tableta posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz marraztu duzu desblokeatzeko eredua, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, telefonoa posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM txartelaren PIN kodea ez da zuzena. Gailua desblokeatzeko, operadorearekin jarri beharko duzu harremanetan."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Ez da zuzena SIM txartelaren PIN kodea. <xliff:g id="NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu gailua desblokeatzeko.</item>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index da5ec73..6fbe804 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"برای باز کردن قفل روی «منو» فشار دهید."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"شبکه قفل شد"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"سیمکارت موجود نیست"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"سیمکارت درون رایانهٔ لوحی نیست."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"سیمکارت درون تلفن نیست."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"سیمکارت را وارد کنید."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"سیمکارت موجود نیست یا قابل خواندن نیست. یک سیمکارت وارد کنید."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"سیمکارت غیرقابل استفاده است."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"یک پین ۴ تا ۸ رقمی را تایپ کنید."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"کد پین باید ۸ عدد یا بیشتر باشد."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"کد پین صحیح را دوباره وارد کنید. تلاشهای مکرر بهطور دائم سیمکارت را غیرفعال خواهد کرد."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"کدهای پین منطبق نیستند"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"تلاشهای زیادی برای کشیدن الگو صورت گرفته است"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"پین خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"گذرواژه خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"الگوی باز کردن قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدید. \n\nلطفاً پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل رایانه لوحی داشتهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، این رایانه لوحی بازنشانی میشود که با آن همه دادههایش حذف میشود."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشتهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، تلفن بازنشانی میشود که با آن همه دادههایش حذف میشود."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل رایانه لوحی داشتهاید. این رایانه لوحی بازنشانی میشود که با آن همه دادههایش حذف میشود."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشتهاید. این تلفن بازنشانی میشود که با آن همه دادههایش حذف میشود."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل رایانه لوحی داشتهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، این کاربر پاک میشود که با آن همه دادههای کاربر حذف میشود."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشتهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، این کاربر پاک میشود که با آن همه دادههای کاربر حذف میشود."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل رایانه لوحی داشتهاید. نمایه کاری پاک میشود که با آن همه دادههای نمایه حذف میشود."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشتهاید. نمایه کاری پاک میشود که با آن همه دادههای نمایه حذف میشود."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"شما الگوی باز کردن قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. بعد از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"شما الگوی باز کردن قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل تلفن را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"کد پین سیمکارت اشتباه است، اکنون برای باز کردن قفل دستگاهتان باید با شرکت مخابراتی تماس بگیرید."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">کد پین سیمکارت اشتباه است، <xliff:g id="NUMBER_1">%d</xliff:g> بار دیگر میتوانید تلاش کنید.</item>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index eec3d12..6d26e36 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Poista lukitus painamalla Valikkoa."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Verkko lukittu"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ei SIM-korttia"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Tabletissa ei ole SIM-korttia."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Puhelimessa ei ole SIM-korttia."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Aseta SIM-kortti."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM-korttia ei löydy tai ei voi lukea. Aseta SIM-kortti."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM-kortti ei käytettävissä"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Anna 4–8-numeroinen PIN-koodi."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-koodissa tulee olla vähintään 8 numeroa."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Anna uudelleen oikea PUK-koodi. Jos teet liian monta yritystä, SIM-kortti poistetaan käytöstä pysyvästi."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-koodit eivät täsmää"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Liikaa kuvionpiirtoyrityksiä"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Olet kirjoittanut PIN-koodin väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunnin kuluttua."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunnin kuluttua."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunnin kuluttua."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Yritit avata tabletin lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos <xliff:g id="NUMBER_1">%2$d</xliff:g> seuraavaa yritystä epäonnistuu, tämä puhelin nollataan ja kaikki sen tiedot poistetaan."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Yritit avata puhelimen lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos <xliff:g id="NUMBER_1">%2$d</xliff:g> seuraavaa yritystä epäonnistuu, tämä puhelin nollataan ja kaikki sen tiedot poistetaan."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Yritit avata tabletin lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER">%d</xliff:g> kertaa. Tämä tabletti nollataan ja kaikki sen tiedot poistetaan."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Yritit avata puhelimen lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER">%d</xliff:g> kertaa. Tämä puhelin nollataan ja kaikki sen tiedot poistetaan."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Yritit avata tabletin lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos <xliff:g id="NUMBER_1">%2$d</xliff:g> seuraavaa yritystä epäonnistuu, tämä käyttäjä ja kaikki sen käyttäjätiedot poistetaan."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Yritit avata puhelimen lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos <xliff:g id="NUMBER_1">%2$d</xliff:g> seuraavaa yritystä epäonnistuu, tämä käyttäjä ja kaikki käyttäjän tiedot poistetaan."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Yritit avata tabletin lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER">%d</xliff:g> kertaa. Työprofiili ja kaikki sen tiedot poistetaan."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Yritit avata puhelimen lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER">%d</xliff:g> kertaa. Työprofiili ja kaikki sen tiedot poistetaan."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään avaamaan tabletin lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään avaamaan puhelimesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Virheellinen SIM-kortin PIN-koodi. Sinun on nyt otettava yhteys operaattoriin laitteen lukituksen avaamiseksi."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Virheellinen SIM-kortin PIN-koodi. Sinulla on <xliff:g id="NUMBER_1">%d</xliff:g> yritystä jäljellä.</item>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index c13ec43..53255af 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Appuyez sur la touche Menu pour déverrouiller l\'appareil."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Réseau verrouillé"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Aucune carte SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Aucune carte SIM n\'est insérée dans la tablette."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Aucune carte SIM n\'est insérée dans le téléphone."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insérez une carte SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Carte SIM absente ou illisible. Veuillez insérer une carte SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Carte SIM inutilisable."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Veuillez entrer un NIP comprenant entre quatre et huit chiffres."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Le code PUK doit contenir au moins 8 chiffres."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Veuillez entrer de nouveau le code PUK correct. Trop de tentatives répétées désactiveront définitivement la carte SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Les NIP ne correspondent pas."</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Trop de tentatives."</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Vous avez entré un NIP incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Vous avez entré un mot de passe incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Vous avez tenté de déverrouiller cette tablette à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> tentative(s) infructueuse(s) supplémentaire(s), cette tablette sera réinitialisée, ce qui entraînera la suppression de toutes les données qu\'elle contient."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Vous avez tenté de déverrouiller ce téléphone à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> tentative(s) infructueuse(s) supplémentaire(s), le téléphone sera réinitialisé, ce qui entraînera la suppression de toutes les données qu\'il contient."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Vous avez tenté de déverrouiller cette tablette à <xliff:g id="NUMBER">%d</xliff:g> reprises. Cette tablette sera réinitialisée, ce qui entraîne la suppression de toutes les données qu\'elle contient."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Vous avez tenté de déverrouiller ce téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Ce téléphone sera réinitialisé, ce qui entraîne la suppression de toutes les données qu\'il contient."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Vous avez tenté de déverrouiller cette tablette à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> tentative(s) infructueuse(s) supplémentaire(s), cet utilisateur sera supprimé, ce qui entraînera la suppression de toutes ses données."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Vous avez tenté de déverrouiller ce téléphone à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> tentative(s) infructueuse(s) supplémentaire(s), cet utilisateur sera supprimé, ce qui entraînera la suppression de toutes ses données."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Vous avez tenté de déverrouiller cette tablette à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel sera supprimé, ce qui entraîne la suppression de toutes ses données."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Vous avez tenté de déverrouiller ce téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel sera supprimé, ce qui entraîne la suppression de toutes ses données."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de courriel.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de courriel.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"NIP de carte SIM incorrect. Vous devez maintenant communiquer avec votre fournisseur de services pour déverrouiller votre appareil."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Le NIP de la carte SIM incorrect. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative.</item>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index 62d2456..ff3ed53 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Appuyez sur \"Menu\" pour déverrouiller le clavier."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Réseau verrouillé"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Pas de carte SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Aucune carte SIM n\'est insérée dans la tablette."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Aucune carte SIM n\'est insérée dans le téléphone."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insérez une carte SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Carte SIM absente ou illisible. Insérez une carte SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"La carte SIM est inutilisable."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Saisissez un code PIN comprenant 4 à 8 chiffres."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"La clé PUK doit contenir au moins 8 chiffres."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Veuillez saisir de nouveau la clé PUK. Après plusieurs tentatives, la carte SIM sera définitivement désactivée."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Les codes PIN ne correspondent pas"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Trop de tentatives"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Vous avez saisi un code incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nRéessayez dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nRéessayez dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nRéessayez dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Vous avez tenté de déverrouiller la tablette à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, elle sera réinitialisée et toutes les données qu\'elle contient seront supprimées."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Vous avez tenté de déverrouiller le téléphone à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, il sera réinitialisé et toutes les données qu\'il contient seront supprimées."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Vous avez tenté de déverrouiller la tablette à <xliff:g id="NUMBER">%d</xliff:g> reprises. Elle va être réinitialisée et toutes les données qu\'elle contient seront supprimées."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Vous avez tenté de déverrouiller le téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Il va être réinitialisé et toutes les données qu\'il contient seront supprimées."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Vous avez tenté de déverrouiller la tablette à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ce compte utilisateur et toutes les données associées seront supprimés."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Vous avez tenté de déverrouiller le téléphone à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ce compte utilisateur et toutes les données associées seront supprimés."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Vous avez tenté de déverrouiller la tablette à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel et toutes les données associées vont être supprimés."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Vous avez tenté de déverrouiller le téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel et toutes les données associées vont être supprimés."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\nRéessayez dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\nRéessayez dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Code PIN de la carte SIM incorrect. Vous devez désormais contacter votre opérateur pour déverrouiller votre appareil."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Code PIN de la carte SIM incorrect. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative.</item>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index aeef9aa..d7f6b6a 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Preme Menú para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada pola rede"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sen tarxeta SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Non hai ningunha tarxeta SIM na tableta."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Non hai ningunha tarxeta SIM no teléfono."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insire unha tarxeta SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Falta a tarxeta SIM ou non se pode ler. Insire unha tarxeta SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Tarxeta SIM inutilizable"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Escribe un PIN que teña entre 4 e 8 números."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"O código PUK debe ter 8 números como mínimo."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Volve introducir o código PUK correcto. Se realizas intentos repetidos é posible que se desactive a tarxeta SIM permanentemente."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Os códigos PIN non coinciden"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Tentaches debuxar o padrón moitas veces"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Introduciches o PIN incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Introduciches o contrasinal incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Debuxaches incorrectamente o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Tentaches desbloquear a tableta <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, restablecerase a tableta e, por conseguinte, eliminaranse todos os seus datos."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, restablecerase o teléfono e, por conseguinte, eliminaranse todos os seus datos."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Tentaches desbloquear a tableta <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Restablecerase a tableta e, por conseguinte, eliminaranse todos os seus datos."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Restablecerase o teléfono e, por conseguinte, eliminaranse todos os seus datos."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Tentaches desbloquear a tableta <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, quitarase este usuario e, por conseguinte, todos os datos do usuario."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, quitarase este usuario e, por conseguinte, todos os datos do usuario."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Tentaches desbloquear a tableta <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Quitarase o perfil de traballo e, por conseguinte, todos os datos do perfil."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Quitarase o perfil de traballo e, por conseguinte, todos os datos do perfil."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Debuxaches o padrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear a tableta a través dunha conta de correo electrónico.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Debuxaches o padrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear o teléfono a través dunha conta de correo electrónico.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"O código PIN da SIM non é correcto. Agora debes contactar co operador para desbloquear o dispositivo."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">O código PIN da SIM é incorrecto. Quédanche <xliff:g id="NUMBER_1">%d</xliff:g> intentos.</item>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index 3f5cab5..c3b7602 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"અનલૉક કરવા માટે મેનૂ દબાવો."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"નેટવર્ક લૉક થયું"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"કોઈ સિમ કાર્ડ નથી"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ટૅબ્લેટમાં સિમ કાર્ડ નથી."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ફોનમાં સિમ કાર્ડ નથી."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"એક સિમ કાર્ડ દાખલ કરો."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"સિમ કાર્ડ ખૂટે છે અથવા વાંચન યોગ્ય નથી. સિમ કાર્ડ દાખલ કરો."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"બિનઉપયોગી સિમ કાર્ડ."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 થી 8 સંખ્યાનો હોય તેવો એક પિન લખો."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK કોડ 8 કે તેનાથી વધુ સંખ્યાનો હોવો જોઈએ."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"સાચો PUK કોડ ફરીથી દાખલ કરો. પુનરાવર્તિત પ્રયાસો સિમ ને કાયમી રીતે અક્ષમ કરશે."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"પિન કોડ મેળ ખાતા નથી"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ઘણા બધા પૅટર્ન પ્રયાસો"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"તમારો પિન તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"તમારો પાસવર્ડ તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"તમારી અનલૉક પૅટર્ન તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"તમે ટૅબ્લેટને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, આ ટૅબ્લેટ ફરીથી સેટ કરવામાં આવશે, જે તેનો તમામ ડેટા કાઢી નાખશે."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"તમે ફોનને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, આ ફોન ફરીથી સેટ કરવામાં આવશે, જે તેનો તમામ ડેટા કાઢી નાખશે."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"તમે ટૅબ્લેટને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. આ ટૅબ્લેટ ફરીથી સેટ થશે, જે તેનો તમામ ડેટા કાઢી નાખશે."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"તમે ફોનને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. આ ફોન ફરીથી સેટ કરાશે, જે તેનો તમામ ડેટા કાઢી નાખશે."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"તમે ટૅબ્લેટને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસો પછી, આ વપરાશકર્તાને દૂર કરવામાં આવશે, જે તમામ વપરાશકર્તા ડેટાને કાઢી નાખશે."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"તમે ફોનને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, આ વપરાશકર્તાને દૂર કરવામાં આવશે, જે તમામ વપરાશકર્તા ડેટા કાઢી નાખશે."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"તમે ટૅબ્લેટને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. આ કાર્યાલયની પ્રોફાઇલ દૂર કરવામાં આવશે, જે તમામ પ્રોફાઇલ ડેટાને કાઢી નાખશે."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"તમે ફોનને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. આ કાર્યાલયની પ્રોફાઇલ દૂર કરવામાં આવશે, જે તમામ પ્રોફાઇલ ડેટાને કાઢી નાખશે."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, તમને એક ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ટૅબ્લેટને અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, તમને ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને ફોન અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ખોટો સિમ પિન કોડ, તમારે હવે તમારું ઉપકરણ અનલૉક કરવા માટે તમારા કૅરીઅરનો સંપર્ક કરવો આવશ્યક છે."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">ખોટો સિમ પિન કોડ, તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index cc8af31..1c5cead 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"लॉक खोलने के लिए मेन्यू दबाएं."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लॉक किया हुआ है"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"कोई SIM कार्ड नहीं है"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"टैबलेट में कोई SIM कार्ड नहीं है."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"फ़ोन में कोई SIM कार्ड नहीं है."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM कार्ड लगाएं."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM कार्ड मौजूद नहीं है या उसे पढ़ा नहीं जा सकता है. कोई SIM कार्ड लगाएं."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"बेकार SIM कार्ड."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"कोई ऐसा पिन लिखें, जिसमें 4 से 8 अंक हों."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK कोड 8 या ज़्यादा संख्या वाला होना चाहिए."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"सही PUK कोड दोबारा डालें. बार-बार कोशिश करने से SIM हमेशा के लिए अक्षम हो जाएगा."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"पिन कोड का मिलान नहीं हो रहा है"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"पैटर्न के लिए बहुत ज़्यादा बार कोशिश की गई है"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"आप अपना पिन <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"आप अपना पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"आपने अपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से ड्रॉ किया है. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"आपने टैबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश की है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल कोशिशों के बाद, इस टैबलेट को रीसेट कर दिया जाएगा, जिससे इसका सारा डेटा हट जाएगा."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"आपने फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश की है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल कोशिशों के बाद, इस फ़ोन को रीसेट कर दिया जाएगा, जिससे इसका सारा डेटा हट जाएगा."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"आपने टैबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से कोशिश की है. इस टैबलेट को रीसेट कर दिया जाएगा, जिससे इसका सारा डेटा हट जाएगा."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"आपने फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से कोशिश की है. इस फ़ोन को रीसेट कर दिया जाएगा, जिससे इसका सारा डेटा हट जाएगा."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"आपने टैबलेट का लॉक खोलने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश की है. <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत कोशिश करने पर, इस उपयोगकर्ता को निकाल दिया जाएगा, जिससे सभी उपयोगकर्ता डेटा मिट जाएगा."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"आपने फ़ोन का लॉक खोलने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश की है. <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत कोशिश करने पर, इस उपयोगकर्ता को निकाल दिया जाएगा, जिससे सभी उपयोगकर्ता डेटा मिट जाएगा."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"आपने टैबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से कोशिश की है. वर्क प्रोफ़ाइल को निकाल दिया जाएगा, जिससे सभी प्रोफ़ाइल डेटा हट जाएगा."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"आपने फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से कोशिश की है. वर्क प्रोफ़ाइल को निकाल दिया जाएगा, जिससे सभी प्रोफ़ाइल डेटा हट जाएगा."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"आपने अपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से ड्रॉ किया है. अगर आपने <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत ड्रॉ किया, तो आपसे अपने टैबलेट को किसी ईमेल खाते का इस्तेमाल करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड बाद फिर से कोशिश करें."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"आपने अपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से ड्रॉ किया है. अगर आपने <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत ड्रॉ किया, तो आपसे अपने फ़ोन को किसी ईमेल खाते का इस्तेमाल करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड बाद फिर से कोशिश करें."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"गलत SIM पिन कोड, अपने डिवाइस को अनलॉक करने के लिए अब आपको अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करना होगा."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">गलत सिम पिन कोड, आप <xliff:g id="NUMBER_1">%d</xliff:g> बार और कोशिश कर सकते हैं.</item>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index 17153e4..ee7a403 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite Izbornik da biste otključali."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nema SIM kartice"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"U tabletu nema SIM kartice."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"U telefonu nema SIM kartice."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Umetnite SIM karticu."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM kartica nedostaje ili nije čitljiva. Umetnite SIM karticu."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM kartica nije upotrebljiva."</string>
@@ -84,17 +82,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Unesite PIN koji ima od 4 do 8 brojeva."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kôd treba imati 8 brojeva ili više."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Ponovo unesite ispravan PUK kôd. Ponovljeni pokušaji trajno će onemogućiti SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodovi nisu jednaki"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Previše pokušaja iscrtavanja uzorka"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Netočno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Netočno ste unijeli zaporku <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Neuspješno ste pokušali otključati tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja tablet će se vratiti na zadano, a time će se izbrisati i svi podaci na njemu."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Neuspješno ste pokušali otključati telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja telefon će se vratiti na zadano, a time će se izbrisati i svi podaci na njemu."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Neuspješno ste pokušali otključati tablet <xliff:g id="NUMBER">%d</xliff:g> put/a. Tablet će se vratiti na zadano, a time će se izbrisati i svi podaci na njemu."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Neuspješno ste pokušali otključati telefon <xliff:g id="NUMBER">%d</xliff:g> put/a. Telefon će se vratiti na zadano, a time će se izbrisati i svi podaci na njemu."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Neuspješno ste pokušali otključati tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja taj će se korisnik ukloniti, a time će se izbrisati i svi njegovi podaci."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Neuspješno ste pokušali otključati telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja taj će se korisnik ukloniti, a time će se izbrisati i svi njegovi podaci."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -103,10 +94,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Neuspješno ste pokušali otključati tablet <xliff:g id="NUMBER">%d</xliff:g> put/a. Radni će se profil ukloniti, a time će se izbrisati i svi njegovi podaci."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Neuspješno ste pokušali otključati telefon <xliff:g id="NUMBER">%d</xliff:g> put/a. Radni će se profil ukloniti, a time će se izbrisati i svi njegovi podaci."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja morat ćete otključati tablet pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja morat ćete otključati telefon pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Netočan PIN kôd SIM kartice; sada morate kontaktirati svog mobilnog operatera da bi otključao vaš uređaj."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">PIN kôd SIM-a nije točan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj.</item>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index 4eb32e9..2f358a0 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"A feloldáshoz nyomja meg a Menü gombot."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Hálózat zárolva"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nincs SIM-kártya"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nincs SIM-kártya a táblagépben."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Nincs SIM-kártya a telefonban."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Helyezzen be SIM-kártyát."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"A SIM-kártya hiányzik vagy nem olvasható. Helyezzen be SIM-kártyát."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"A SIM-kártya nem használható."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Írjon be egy 4-8 számjegyű PIN-kódot."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"A PUK-kódnak legalább nyolc számjegyből kell állnia."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Adja meg újra a helyes PUK-kódot. Az ismételt próbálkozásokkal véglegesen letiltja a SIM-kártyát."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"A PIN-kódok nem egyeznek"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Túl sok mintarajzolási próbálkozás"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül adta meg a PIN-kódot.\n\nPróbálja újra <xliff:g id="NUMBER_1">%2$d</xliff:g> másodperc múlva."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül adta meg a jelszót.\n\nPróbálja újra <xliff:g id="NUMBER_1">%2$d</xliff:g> másodperc múlva."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal rosszul rajzolta le a feloldási mintát.\n\nPróbálja újra <xliff:g id="NUMBER_1">%2$d</xliff:g> másodperc múlva."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálkozott sikertelenül a táblagép zárolásának feloldásával. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után a rendszer visszaállítja a táblagépet, és ezzel az összes adat törlődik róla."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálkozott sikertelenül a telefon zárolásának feloldásával. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után a rendszer visszaállítja a telefont, és ezzel az összes adat törlődik róla."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálkozott sikertelenül a táblagép zárolásának feloldásával. A rendszer visszaállítja a táblagépet, és ezzel a rajta lévő összes adat törlődik."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálkozott sikertelenül a telefon zárolásának feloldásával. A rendszer visszaállítja a telefont, és ezzel a rajta lévő összes adat törlődik."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálkozott sikertelenül a táblagép zárolásának feloldásával. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után a rendszer eltávolítja a felhasználót, és ezzel a felhasználó összes adata törlődik majd."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálkozott sikertelenül a telefon zárolásának feloldásával. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után a rendszer eltávolítja a felhasználót, és ezzel a felhasználó összes adata törlődik majd."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálkozott sikertelenül a táblagép zárolásának feloldásával. A rendszer eltávolítja a munkaprofilt, és ezzel a profil összes adata törlődik."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálkozott sikertelenül a telefon zárolásának feloldásával. A rendszer eltávolítja a munkaprofilt, és ezzel a profil összes adata törlődik."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után e-mail-fiók használatával kell feloldania táblagépét.\n\nPróbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után e-mail-fiók használatával kell feloldania telefonját.\n\nPróbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Helytelen PIN-kód a SIM-kártyához. Az eszköz feloldása érdekében, kérjük, vegye fel a kapcsolatot szolgáltatójával."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Helytelen PIN-kód a SIM-kártyához. Még <xliff:g id="NUMBER_1">%d</xliff:g> próbálkozása maradt.</item>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index c0d1c93..7da8ed4 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ապակողպելու համար սեղմեք Ընտրացանկը:"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Ցանցը կողպված է"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM քարտ չկա"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Պլանշետում SIM քարտ չկա:"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Հեռախոսում SIM քարտ չկա:"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Տեղադրեք SIM քարտ:"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM քարտը բացակայում է կամ ընթեռնելի չէ: Տեղադրեք SIM քարտ:"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Անպիտան SIM քարտ:"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Մուտքագրեք 4-8 թվանշան պարունակող PIN կոդ։"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK կոդը պետք է առնվազն 8 թվանշան պարունակի։"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Վերամուտքագրեք ճիշտ PUK կոդը: Կրկնվող փորձերը ընդմիշտ կարգելափակեն SIM քարտը:"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN կոդերը չեն համընկնում"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Նախշը մուտքագրելու չափազանց շատ փորձեր են կատարվել"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Դուք սխալ եք մուտքագրել ձեր PIN կոդը <xliff:g id="NUMBER_0">%1$d</xliff:g> անգամ: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%2$d</xliff:g> վայրկյանից։"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Դուք սխալ եք մուտքագրել ձեր գաղտնաբառը <xliff:g id="NUMBER_0">%1$d</xliff:g> անգամ: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%2$d</xliff:g> վայրկյանից:"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Դուք սխալ եք մուտքագրել ձեր ապակողպման նախշը <xliff:g id="NUMBER_0">%1$d</xliff:g> անգամ: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%2$d</xliff:g> վայրկյանից։"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Դուք կատարել եք պլանշետն ապակողպելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո այս պլանշետը կվերակայվի և բոլոր տվյալները կջնջվեն:"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Դուք կատարել եք հեռախոսն ապակողպելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո այս հեռախոսը կվերակայվի և բոլոր տվյալները կջնջվեն:"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Դուք կատարել եք պլանշետն ապակողպելու <xliff:g id="NUMBER">%d</xliff:g> անհաջող փորձ: Այս պլանշետը կվերակայվի և բոլոր տվյալները կջնջվեն:"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Դուք կատարել եք հեռախոսն ապակողպելու <xliff:g id="NUMBER">%d</xliff:g> անհաջող փորձ: Այս հեռախոսը կվերակայվի և բոլոր տվյալները կջնջվեն:"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Դուք կատարել եք պլանշետն ապակողպելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո այս օգտվողը կհեռացվի և օգտվողի բոլոր տվյալները կջնջվեն:"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Դուք կատարել եք հեռախոսն ապակողպելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո այս օգտվողը կհեռացվի և օգտվողի բոլոր տվյալները կջնջվեն:"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Դուք կատարել եք պլանշետն ապակողպելու <xliff:g id="NUMBER">%d</xliff:g> անհաջող փորձ: Աշխատանքային պրոֆիլը կհեռացվի և պրոֆիլի բոլոր տվյալները կջնջվեն:"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Դուք կատարել եք հեռախոսն ապակողպելու <xliff:g id="NUMBER">%d</xliff:g> անհաջող փորձ: Աշխատանքային պրոֆիլը կհեռացվի և պրոֆիլի բոլոր տվյալները կջնջվեն:"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Դուք կատարել եք ապակողպման նախշը մուտքագրելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել պլանշետը էլփոստի հաշվի միջոցով։\n\n Խնդրում ենք փորձել կրկին <xliff:g id="NUMBER_2">%3$d</xliff:g> վայրկյանից:"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Դուք կատարել եք ապակողպման նախշը մուտքագրելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել հեռախոսը էլփոստի հաշվի միջոցով։\n\n Խնդրում ենք փորձել կրկին <xliff:g id="NUMBER_2">%3$d</xliff:g> վայրկյանից:"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM PIN կոդը սխալ է։ Այժմ պետք է դիմեք ձեր օպերատորին՝ սարքն արգելահանելու համար:"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Incorrect SIM PIN code, you have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index 8772d89..406b00e 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tekan Menu untuk membuka kunci."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Jaringan terkunci"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Tidak ada kartu SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Tidak ada kartu SIM dalam tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Tidak ada Kartu SIM di dalam ponsel."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Masukkan kartu SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Kartu SIM tidak ada atau tidak dapat dibaca. Masukkan kartu SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Kartu SIM tidak dapat digunakan."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Ketikkan PIN berupa 4 sampai 8 angka."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Kode PUK harus terdiri dari 8 angka atau lebih."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Masukkan kembali kode PUK yang benar. Jika berulang kali gagal, SIM akan dinonaktifkan secara permanen."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kode PIN tidak cocok"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Terlalu banyak upaya pola"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah mengetik PIN. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah mengetik sandi. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda berupaya membuka kunci tablet dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, tablet ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda berupaya membuka kunci ponsel dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, ponsel ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Sudah <xliff:g id="NUMBER">%d</xliff:g> kali Anda berupaya membuka kunci tablet dengan tidak benar. Tablet ini akan disetel ulang, sehingga menghapus semua datanya."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Sudah <xliff:g id="NUMBER">%d</xliff:g> kali Anda berupaya membuka kunci ponsel dengan tidak benar. Ponsel ini akan disetel ulang, sehingga menghapus semua datanya."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda berupaya membuka kunci tablet dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda berupaya membuka kunci ponsel dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Sudah <xliff:g id="NUMBER">%d</xliff:g> kali Anda berupaya membuka kunci tablet dengan tidak benar. Profil kerja akan dihapus, sehingga menghapus semua data profil."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Sudah <xliff:g id="NUMBER">%d</xliff:g> kali Anda berupaya membuka kunci ponsel dengan tidak benar. Profil kerja akan dihapus, sehingga menghapus semua data profil."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, Anda akan diminta membuka kunci tablet menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, Anda akan diminta membuka kunci ponsel menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Kode PIN SIM salah. Hubungi operator untuk membuka kunci perangkat."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Kode PIN SIM salah, sisa, sisa <xliff:g id="NUMBER_1">%d</xliff:g> percobaan.</item>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index bece625..4f87df6 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ýttu á valmyndarhnappinn til að taka úr lás."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Net læst"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ekkert SIM-kort"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Ekkert SIM-kort í spjaldtölvunni."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Ekkert SIM-kort í símanum."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Settu SIM-kort í."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM-kort vantar eða það er ekki læsilegt. Settu SIM-kort í."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Ónothæft SIM-kort."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Sláðu in PIN-númer sem er 4 til 8 tölustafir."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-númerið verður að vera 8 tölustafir eða lengra."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Prófaðu aftur að setja inn rétt PUK-númer. Endurteknar tilraunir gera SIM-kortið varanlega óvirkt."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-númerin stemma ekki"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Of margar tilraunir til að teikna mynstur"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Þú hefur slegið inn rangt PIN-númer <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> sekúndur."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Þú hefur slegið inn rangt aðgangsorð <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> sekúndur."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> sekúndur."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> árangurslausar tilraunir til að opna spjaldtölvuna. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður spjaldtölvan endurstillt, með þeim afleiðingum að öllum gögnum hennar verður eytt."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> árangurslausar tilraunir til að opna símann. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður síminn endurstilltur, með þeim afleiðingum að öllum gögnum hans verður eytt."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að opna spjaldtölvuna. Spjaldtölvan verður endurstillt, með þeim afleiðingum að öllum gögnum hennar verður eytt."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að opna símann. Síminn verður endurstilltur, með þeim afleiðingum að öllum gögnum hans verður eytt."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> árangurslausar tilraunir til að opna spjaldtölvuna. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður notandinn fjarlægður með þeim afleiðingum að öllum notandagögnum verður eytt."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> árangurslausar tilraunir til að opna símann. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður notandinn fjarlægður með þeim afleiðingum að öllum notandagögnum verður eytt."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að opna spjaldtölvuna. Vinnusniðið verður fjarlægt, með þeim afleiðingum að öllum gögnum þess verður eytt."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að opna símann. Vinnusniðið verður fjarlægt, með þeim afleiðingum að öllum gögnum þess verður eytt."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður þú beðin(n) um að opna spjaldtölvuna með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verðurðu beðin(n) um að opna símann með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Rangt PIN-númer SIM-korts. Nú þarftu að hafa samband við símafyrirtækið til að opna fyrir tækið."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Rangt PIN-númer SIM-korts. Þú átt <xliff:g id="NUMBER_1">%d</xliff:g> tilraun eftir.</item>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index cd27ba4..f714bf7 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Premi Menu per sbloccare."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rete bloccata"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nessuna SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nessuna scheda SIM presente nel tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Nessuna scheda SIM presente nel telefono."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Inserisci una scheda SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Scheda SIM mancante o non leggibile. Inserisci una scheda SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Scheda SIM inutilizzabile."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Il PIN deve essere di 4-8 numeri."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Il codice PUK dovrebbe avere almeno otto numeri."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Inserisci di nuovo il codice PUK corretto. Ripetuti tentativi comportano la disattivazione definitiva della scheda SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"I codici PIN non corrispondono"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Troppi tentativi di inserimento della sequenza"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Hai digitato la tua password <xliff:g id="NUMBER_0">%1$d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Hai tentato di sbloccare il tablet senza riuscirci per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, il tablet verrà ripristinato e verranno quindi eliminati tutti i relativi dati."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Hai tentato di sbloccare il telefono senza riuscirci per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, il telefono verrà ripristinato e verranno quindi eliminati tutti i relativi dati."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Hai tentato di sbloccare il tablet senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Il tablet verrà ripristinato e verranno quindi eliminati tutti i relativi dati."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Hai tentato di sbloccare il telefono senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Il telefono verrà ripristinato e verranno quindi eliminati tutti i relativi dati."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Hai tentato di sbloccare il tablet senza riuscirci per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, questo utente verrà rimosso e verranno quindi eliminati tutti i dati associati."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Hai tentato di sbloccare il telefono senza riuscirci per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, questo utente verrà rimosso e verranno quindi eliminati tutti i dati associati."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Hai tentato di sbloccare il tablet senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Il profilo di lavoro verrà rimosso e verranno quindi eliminati tutti i dati associati."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Hai tentato di sbloccare il telefono senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Il profilo di lavoro verrà rimosso e verranno quindi eliminati tutti i dati associati."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Codice PIN della SIM errato. Devi contattare l\'operatore per sbloccare il dispositivo."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Codice PIN della SIM errato. Hai ancora <xliff:g id="NUMBER_1">%d</xliff:g> tentativi a disposizione.</item>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index d715637..2af5192 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"לחץ על \'תפריט\' כדי לבטל את הנעילה."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"הרשת נעולה"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"אין כרטיס SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"אין כרטיס SIM בטאבלט."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"אין כרטיס SIM בטלפון."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"הכנס כרטיס SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"כרטיס ה-SIM חסר או שלא ניתן לקרוא אותו. הכנס כרטיס SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"לא ניתן להשתמש בכרטיס SIM זה."</string>
@@ -85,17 +83,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"הקלד קוד גישה שאורכו 4 עד 8 ספרות."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"קוד PUK צריך להיות בן 8 ספרות או יותר."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"הזן את קוד ה-PUK הנכון. ניסיונות חוזרים ישביתו את כרטיס ה-SIM לצמיתות."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"קודי הגישה אינם תואמים"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ניסית לשרטט את קו ביטול הנעילה יותר מדי פעמים"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"הקלדת קוד גישה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים.\n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, טאבלט זה יאופס וכל הנתונים שבו יימחקו."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, טלפון זה יאופס וכל הנתונים שבו יימחקו."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER">%d</xliff:g> פעמים. הטאבלט יאופס וכל הנתונים שלו יימחקו."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. הטלפון יאופס וכל הנתונים שבו יימחקו."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, משתמש זה יוסר וכל נתוני המשתמש יימחקו."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, משתמש זה יוסר וכל נתוני המשתמש יימחקו."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -104,10 +95,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER">%d</xliff:g> פעמים. פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון אימייל.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון אימייל.\n\n נסה שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"קוד הגישה של כרטיס ה-SIM שגוי. צור קשר עם הספק כדי לבטל את נעילת המכשיר."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="two">קוד הגישה של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 3ed6fec..5f0d83f 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"メニューからロックを解除できます。"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ネットワークがロックされました"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM カードなし"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"タブレットに SIM カードが挿入されていません。"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"スマートフォンに SIM カードが挿入されていません。"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM カードを挿入してください。"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM カードが見つからないか読み取れません。SIM カードを挿入してください。"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM カードは使用できません。"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"PIN は 4~8 桁の数字で入力してください。"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK コードは 8 桁以下の数字で入力してください。"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"正しい PUK コードを再入力してください。誤入力を繰り返すと、SIM が完全に無効になる恐れがあります。"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN コードが一致しません"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"パターンの入力を所定の回数以上間違えました"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN の入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後にもう一度お試しください。"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"パスワードの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後にもう一度お試しください。"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ロック解除パターンの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後にもう一度お試しください。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"タブレットのロック解除に <xliff:g id="NUMBER_0">%1$d</xliff:g> 回失敗しました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回失敗すると、このタブレットはリセットされ、データはすべて消去されます。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"スマートフォンのロック解除に <xliff:g id="NUMBER_0">%1$d</xliff:g> 回失敗しました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回失敗すると、このスマートフォンはリセットされ、データはすべて消去されます。"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"タブレットのロック解除に <xliff:g id="NUMBER">%d</xliff:g> 回失敗しました。このタブレットはリセットされ、データはすべて消去されます。"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"スマートフォンのロック解除に <xliff:g id="NUMBER">%d</xliff:g> 回失敗しました。このスマートフォンはリセットされ、データはすべて消去されます。"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"タブレットのロック解除に <xliff:g id="NUMBER_0">%1$d</xliff:g> 回失敗しました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回失敗すると、このユーザーは削除され、ユーザー データはすべて消去されます。"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"スマートフォンのロック解除に <xliff:g id="NUMBER_0">%1$d</xliff:g> 回失敗しました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回失敗すると、このユーザーは削除され、ユーザー データはすべて消去されます。"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"タブレットのロック解除に <xliff:g id="NUMBER">%d</xliff:g> 回失敗しました。仕事用プロファイルは削除され、プロファイルのデータはすべて消去されます。"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"スマートフォンのロック解除に <xliff:g id="NUMBER">%d</xliff:g> 回失敗しました。仕事用プロファイルは削除され、プロファイルのデータはすべて消去されます。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ロック解除パターンの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回間違えると、タブレットのロック解除にメール アカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後にもう一度お試しください。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ロック解除パターンの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回間違えると、スマートフォンのロック解除にメール アカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後にもう一度お試しください。"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM PIN コードが無効です。お使いのデバイスをロック解除するには携帯通信会社にお問い合わせいただく必要があります。"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM PIN コードが無効です。入力できるのはあと <xliff:g id="NUMBER_1">%d</xliff:g> 回です。</item>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index cf170e4..cd1719b 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"განსაბლოკად დააჭირეთ მენიუს."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ქსელი ჩაკეტილია"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM ბარათი არ არის"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ტაბლეტში არ არის SIM ბარათი."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ტელეფონში არ არის SIM ბარათი."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"ჩადეთ SIM ბარათი."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM ბარათი არ არის ან არ იკითხება. ჩადეთ SIM ბარათი."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM ბარათი გამოუსადეგარია."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"აკრიფეთ 4-8 ციფრისგან შემდგარი PIN-კოდი."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-კოდი 8 ან მეტი ციფრისგან უნდა შედგებოდეს."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"ხელახლა შეიყვანეთ სწორი PUK-კოდი. რამდენიმე წარუმატებელი მცდელობის შემთხვევაში, SIM ბარათი სამუდამოდ გამოუსადეგარი გახდება."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-კოდები არ ემთხვევა"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ნიმუში დახატულია არასწორად მეტისმეტად ბევრჯერ"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"თქვენ არასწორად შეიყვანეთ PIN-კოდი <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. \n\nცადეთ ხელახლა <xliff:g id="NUMBER_1">%2$d</xliff:g> წამში."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"თქვენ არასწორად აკრიფეთ პაროლი <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. \n\nცადეთ ხელახლა <xliff:g id="NUMBER_1">%2$d</xliff:g> წამში."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"თქვენ არასწორად დახატეთ განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. \n\nცადეთ ხელახლა <xliff:g id="NUMBER_1">%2$d</xliff:g> წამში."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"თქვენ არასწორად ცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ამ ტაბლეტის გადაყენება განხორციელდება, რაც მისი მონაცემების მთლიანად წაშლას გამოიწვევს."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"თქვენ არასწორად ცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ამ ტელეფონის გადაყენება განხორციელდება, რაც მისი მონაცემების მთლიანად წაშლას გამოიწვევს."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"თქვენ არასწორად ცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER">%d</xliff:g>-ჯერ. ამის გამო, ამ ტაბლეტის გადაყენება განხორციელდება, რაც მისი მონაცემების მთლიანად წაშლას გამოიწვევს."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"თქვენ არასწორად ცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER">%d</xliff:g>-ჯერ. ამის გამო, ამ ტელეფონის გადაყენება განხორციელდება, რაც მისი მონაცემების მთლიანად წაშლას გამოიწვევს."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"თქვენ არასწორად ცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ეს მომხმარებელი ამოიშლება, რაც მომხმარებლის ყველა მონაცემის წაშლას გამოიწვევს."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"თქვენ არასწორად ცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ეს მომხმარებელი ამოიშლება, რაც მომხმარებლის ყველა მონაცემის წაშლას გამოიწვევს."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"თქვენ არასწორად ცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER">%d</xliff:g>-ჯერ. ამის გამო, სამსახურის პროფილი ამოიშლება, რაც პროფილის ყველა მონაცემის წაშლას გამოიწვევს."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"თქვენ არასწორად ცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER">%d</xliff:g>-ჯერ. ამის გამო, სამსახურის პროფილი ამოიშლება, რაც პროფილის ყველა მონაცემის წაშლას გამოიწვევს."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ტაბლეტის განბლოკვა თქვენი ელფოსტის ანგარიშის მეშვეობით მოგიწევთ.\n\n ცადეთ ხელახლა <xliff:g id="NUMBER_2">%3$d</xliff:g> წამში."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ტელეფონის განბლოკვა თქვენი ელფოსტის ანგარიშის მეშვეობით მოგიწევთ.\n\n ცადეთ ხელახლა <xliff:g id="NUMBER_2">%3$d</xliff:g> წამში."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM ბარათის PIN-კოდი არასწორია. ახლა თქვენი მოწყობილობის განსაბლოკად თქვენს ოპერატორთან დაკავშირება მოგიწევთ."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM ბარათის PIN-კოდი არასწორია. თქვენ დაგრჩათ <xliff:g id="NUMBER_1">%d</xliff:g> მცდელობა.</item>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 53c1138..0b78b57 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ашу үшін \"Мәзір\" пернесін басыңыз."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Желі құлыптаулы"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM картасы салынбаған"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Планшетте SIM картасы жоқ."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Телефонда SIM картасы жоқ."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM картасын енгізіңіз."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM картасы жоқ немесе оқылмайды. SIM картасын салыңыз."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM картасы қолданыстан шыққан."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4-8 саннан тұратын PIN кодын енгізіңіз."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK коды 8 не одан көп саннан тұруы қажет."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Дұрыс PUK кодын қайта енгізіңіз. Әрекетті қайталай берсеңіз, SIM картасы өшіріледі."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN коды сәйкес келмейді"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Тым көп өрнек енгізу әрекеті жасалды"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN коды <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундтан кейін әркетті қайталаңыз."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Құпия сөз <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Құлыпты ашу өрнегі <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Планшет құлпын ашуға <xliff:g id="NUMBER_0">%1$d</xliff:g> рет сәтсіз әрекет жасалды. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін осы планшет бастапқы күйіне қайтарылып, оның бүкіл деректері жойылады."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Телефон құлпын ашуға <xliff:g id="NUMBER_0">%1$d</xliff:g> рет сәтсіз әрекет жасалды. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін осы телефон бастапқы күйіне қайтарылып, оның бүкіл деректері жойылады."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Планшет құлпын ашуға <xliff:g id="NUMBER">%d</xliff:g> рет сәтсіз әрекет жасалды. Осы планшет бастапқы күйіне қайтарылып, оның бүкіл деректері жойылады."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Телефон құлпын ашуға <xliff:g id="NUMBER">%d</xliff:g> рет сәтсіз әрекет жасалды. Осы телефон бастапқы күйіне қайтарылып, оның бүкіл деректері жойылады."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Планшет құлпын ашуға <xliff:g id="NUMBER_0">%1$d</xliff:g> рет сәтсіз әрекет жасалды. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін пайдаланушы өшіріліп, оның бүкіл деректері жойылады."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Телефон құлпын ашуға <xliff:g id="NUMBER_0">%1$d</xliff:g> рет сәтсіз әрекет жасалды. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін пайдаланушы өшіріліп, оның бүкіл деректері жойылады."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Планшет құлпын ашуға <xliff:g id="NUMBER">%d</xliff:g> рет сәтсіз әрекет жасалды. Жұмыс профилі өшіріліп, оның бүкіл деректері жойылады."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Телефон құлпын ашуға <xliff:g id="NUMBER">%d</xliff:g> рет сәтсіз әрекет жасалды. Жұмыс профилі өшіріліп, оның бүкіл деректері жойылады."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Құлыпты ашу өрнегі <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін планшетті есептік жазба арқылы ашу сұралады. \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Құлыпты ашу өрнегі <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін телефонды есептік жазба арқылы ашу сұралады. \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM PIN коды дұрыс емес, операторға хабарласып, құрылғының құлпын ашуды сұраңыз."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM PIN коды дұрыс емес. <xliff:g id="NUMBER_1">%d</xliff:g> әрекет қалды.</item>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index 0e4b418..a07c299 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ចុចម៉ឺនុយ ដើម្បីដោះសោ។"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"បណ្ដាញជាប់សោ"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"គ្មានស៊ីមកាតទេ"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"គ្មានស៊ីមកាតនៅក្នុងថេប្លេតទេ។"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"គ្មានស៊ីមកាតនៅក្នុងទូរសព្ទទេ។"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"ស៊កបញ្ចូលស៊ីមកាត។"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"ស៊ីមកាតបានបាត់ ឬមិនអាចអានបាន។ សូមស៊កបញ្ចូលស៊ីមកាត។"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"ស៊ីមកាតមិនអាចប្រើបានទេ។"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"វាយបញ្ចូលកូដ PIN ចន្លោះពី 4 ទៅ 8 ខ្ទង់"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"កូដ PUK គួរតែមានលេខ 8 ខ្ទង់ ឬច្រើនជាងនេះ។"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"សូមបញ្ចូលកូដ PUK ម្ដងទៀត។ ការព្យាយាមដដែលច្រើនដងនឹងបិទដំណើរការស៊ីមនេះជាអចិន្ត្រៃយ៍។"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"កូដ PIN មិនត្រូវគ្នាទេ"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ការព្យាយាមបញ្ចូលលំនាំច្រើនដងពេកហើយ"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"អ្នកបានវាយបញ្ចូលកូដ PIN របស់អ្នកមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ \n\nសូមព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER_1">%2$d</xliff:g> វិនាទីទៀត។"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"អ្នកបានវាយបញ្ចូលពាក្យសម្ងាត់របស់អ្នកមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ \n\nសូមព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER_1">%2$d</xliff:g> វិនាទីទៀត។"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"អ្នកបានគូរលំនាំដោះសោរបស់អ្នកមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ \n\nសូមព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER_1">%2$d</xliff:g> វិនាទីទៀត។"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"អ្នកបានព្យាយាមដោះសោថេប្លេតនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ ថេប្លេតនេះនឹងត្រូវបានកំណត់ឡើងវិញ ហើយវានឹងលុបទិន្នន័យរបស់វាទាំងអស់។"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"អ្នកបានព្យាយាមដោះសោទូរសព្ទនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ ទូរសព្ទនេះនឹងត្រូវបានកំណត់ឡើងវិញ ហើយវានឹងលុបទិន្នន័យរបស់វាទាំងអស់។"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"អ្នកបានព្យាយាមដោះសោថេប្លេតនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដង។ ថេប្លេតនេះនឹងត្រូវបានកំណត់ឡើងវិញ ហើយវានឹងលុបទិន្នន័យទាំងអស់របស់វា។"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"អ្នកបានព្យាយាមដោះសោទូរសព្ទនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដងហើយ។ ទូរសព្ទនេះនឹងត្រូវបានកំណត់ឡើងវិញ ហើយវានឹងលុបទិន្នន័យទាំងអស់របស់វា។"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"អ្នកបានព្យាយាមដោះសោថេប្លេតនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ អ្នកប្រើប្រាស់នេះនឹងត្រូវបានលុប ហើយវានឹងលុបទិន្នន័យរបស់អ្នកប្រើប្រាស់ទាំងអស់។"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"អ្នកបានព្យាយាមដោះសោទូរសព្ទនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ អ្នកប្រើប្រាស់នេះនឹងត្រូវបានលុប ហើយវានឹងលុបទិន្នន័យរបស់អ្នកប្រើប្រាស់ទាំងអស់។"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"អ្នកបានព្យាយាមដោះសោថេប្លេតនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដងហើយ។ កម្រងព័ត៌មានការងារនេះនឹងត្រូវបានលុប ហើយវានឹងលុបទិន្នន័យកម្រងព័ត៌មានទាំងអស់។"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"អ្នកបានព្យាយាមដោះសោទូរសព្ទនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដងហើយ។ កម្រងព័ត៌មានការងារនេះនឹងត្រូវបានលុប ហើយវានឹងលុបទិន្នន័យកម្រងព័ត៌មានទាំងអស់។"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"អ្នកបានគូរលំនាំដោះសោរបស់អ្នកមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ អ្នកនឹងត្រូវបានស្នើឲ្យដោះសោថេប្លេតរបស់អ្នក ដោយប្រើគណនីអ៊ីមែល។\n\n សូមព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER_2">%3$d</xliff:g> វិនាទីទៀត។"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"អ្នកបានគូរលំនាំដោះសោរបស់អ្នកមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ អ្នកនឹងត្រូវបានស្នើឲ្យដោះសោទូរសព្ទរបស់អ្នក ដោយប្រើគណនីអ៊ីមែល។\n\n សូមព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER_2">%3$d</xliff:g> វិនាទីទៀត។"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"កូដ PIN របស់ស៊ីមមិនត្រឹមត្រូវទេ អ្នកត្រូវទាក់ទងទៅក្រុមហ៊ុនបម្រើសេវាទូរសព្ទរបស់អ្នកឥឡូវនេះ ដើម្បីដោះសោឧបករណ៍របស់អ្នក។"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">កូដ PIN របស់ស៊ីមមិនត្រឹមត្រូវទេ អ្នកអាចព្យាយាមបាន <xliff:g id="NUMBER_1">%d</xliff:g> ដងទៀត។</item>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index 1d162e8..2c88419 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಮೆನು ಒತ್ತಿರಿ."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ನೆಟ್ವರ್ಕ್ ಲಾಕ್ ಆಗಿದೆ"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ಪೋನ್ನಲ್ಲಿ ಯಾವುದೇ ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"ಸಿಮ್ ಕಾರ್ಡ್ ಸೇರಿಸಿ."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ ಅಥವಾ ಗುರುತಿಸಲು ಅಸಾಧ್ಯ. ಒಂದು ಸಿಮ್ ಕಾರ್ಡ್ ಸೇರಿಸಿ."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"ನಿಷ್ಪ್ರಯೋಜಕ ಸಿಮ್ ಕಾರ್ಡ್."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 ರಿಂದ 8 ಸಂಖ್ಯೆಗಳಿರುವ ಪಿನ್ ಟೈಪ್ ಮಾಡಿ."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK ಕೋಡ್ 8 ಅಥವಾ ಹೆಚ್ಚು ಸಂಖ್ಯೆಗಳನ್ನು ಹೊಂದಿರಬೇಕು."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"ಸರಿಯಾದ PUK ಕೋಡ್ ಮರು-ನಮೂದಿಸಿ. ಸತತ ಪ್ರಯತ್ನಗಳು ಸಿಮ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ಪಿನ್ ಕೋಡ್ಗಳು ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ಪ್ಯಾಟರ್ನ್ ಪ್ರಯತ್ನಗಳ ಮಿತಿ ಮುಗಿದಿದೆ"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"ನಿಮ್ಮ ಪಿನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ್ದೀರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ನಮೂದಿಸಿದ್ದೀರಿ. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಎಳೆದಿದ್ದೀರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಈ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ, ಇದು ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ಫೋನ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಈ ಫೋನ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ, ಇದು ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಈ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ, ಇದು ಅದರ ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಈ ಫೋನ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ, ಇದು ಅದರ ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಈ ಬಳಕೆದಾರರನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ, ಇದು ಬಳಕೆದಾರರ ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ಫೋನ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಈ ಬಳಕೆದಾರರನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ, ಇದು ಬಳಕೆದಾರರ ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ, ಇದು ಎಲ್ಲ ಪ್ರೊಫೈಲ್ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ, ಇದು ಎಲ್ಲ ಪ್ರೊಫೈಲ್ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಎಳೆದಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ನಿಮ್ಮ ಇಮೇಲ್ ಖಾತೆಯನ್ನು ಬಳಸಿ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡುವಂತೆ ನಿಮ್ಮಲ್ಲಿ ಕೇಳಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಎಳೆದಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ನಿಮ್ಮ ಇಮೇಲ್ ಖಾತೆಯನ್ನು ಬಳಸಿ ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡುವಂತೆ ನಿಮ್ಮಲ್ಲಿ ಕೇಳಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ಸಿಮ್ ಪಿನ್ ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು ಈ ಕೂಡಲೇ ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಬೇಕು."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">ಸಿಮ್ ಪಿನ್ ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, ನಿಮಗೆ <xliff:g id="NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index c0fb716..bdbd3d9 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"잠금 해제하려면 메뉴를 누르세요."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"네트워크 잠김"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM 카드 없음"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"태블릿에 SIM 카드가 없습니다."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"휴대전화에 SIM 카드가 없습니다."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM 카드를 삽입하세요."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM 카드가 없거나 읽을 수 없는 상태입니다. SIM 카드를 삽입하세요."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"사용할 수 없는 SIM 카드입니다."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4~8자리 숫자로 된 PIN을 입력하세요."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK 코드는 8자리 이상의 숫자여야 합니다."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"올바른 PUK 코드를 다시 입력하세요. 입력을 반복해서 시도하면 SIM이 영구적으로 사용 중지됩니다."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN 코드가 일치하지 않음"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"패턴 그리기를 너무 많이 시도함"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN을 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g>초 후에 다시 시도하세요."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"비밀번호를 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g>초 후에 다시 시도하세요."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 잘못 그렸습니다. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g>초 후에 다시 시도하세요."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"태블릿 잠금 해제에 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 실패했습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 태블릿이 재설정되며 모든 데이터가 삭제됩니다."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"휴대전화 잠금 해제에 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 실패했습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 휴대전화가 재설정되며 모든 데이터가 삭제됩니다."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"태블릿 잠금 해제에 <xliff:g id="NUMBER">%d</xliff:g>번 실패했습니다. 태블릿이 재설정되며 모든 데이터가 삭제됩니다."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"휴대전화 잠금 해제에 <xliff:g id="NUMBER">%d</xliff:g>번 실패했습니다. 휴대전화가 재설정되며 모든 데이터가 삭제됩니다."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"태블릿 잠금 해제에 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 실패했습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 이 사용자와 모든 사용자 데이터가 삭제됩니다."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"휴대전화 잠금 해제에 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 실패했습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 이 사용자와 모든 사용자 데이터가 삭제됩니다."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"태블릿 잠금 해제에 <xliff:g id="NUMBER">%d</xliff:g>번 실패했습니다. 직장 프로필과 모든 프로필 데이터가 삭제됩니다."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"휴대전화 잠금 해제에 <xliff:g id="NUMBER">%d</xliff:g>번 실패했습니다. 직장 프로필과 모든 프로필 데이터가 삭제됩니다."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 잘못 그렸습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금 해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g>초 후에 다시 시도해 주세요."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 잘못 그렸습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금 해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g>초 후에 다시 시도해 주세요."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"잘못된 SIM PIN코드입니다. 이동통신사에 문의하여 기기를 잠금 해제해야 합니다."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">잘못된 SIM PIN 코드입니다. 입력을 <xliff:g id="NUMBER_1">%d</xliff:g>번 더 시도할 수 있습니다.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 32a3346..8e9c794 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Кулпуну ачуу үчүн Менюну басыңыз."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Тармак кулпуланган"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM карта жок"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Планшетте SIM-карта жок."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Телефондо SIM-карта жок."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM-карта салыңыз."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM-карта жок же ал окулбай калган. SIM-карта салыңыз."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Жараксыз SIM-карта."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4–8 сандан турган PIN-кодду териңиз."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-код 8 же андан көп сандан турушу керек."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"PUK-кодду кайрадан туура киргизиңиз. Кайталанган аракеттер SIM-картаны биротоло жараксыз кылат."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-коддор дал келген жок"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Өтө көп графикалык ачкычты тартуу аракети болду"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN-кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секунддан кийин дагы аракет кылып көрүңүз."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секунддан кийин дагы аракет кылып көрүңүз."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Кулпуну ачуучу графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секунддан кийин дагы аракет кылып көрүңүз."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Планшеттин кулпусун <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу ийгиликсиз аракет кылсаңыз, бул планшет баштапкы абалга келтирилип, андагы бардык дайындар жок болот."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Телефондун кулпусун <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу ийгиликсиз аракет кылсаңыз, бул телефон баштапкы абалга келтирилип, андагы бардык дайындар жок болот."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Планшеттин кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Бул планшет баштапкы абалга келтирилип, андагы бардык дайындар жок болот."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Телефондун кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес аракет жасадыңыз. Бул телефон баштапкы абалга келтирилип, андагы бардык дайындар жок болот."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Планшеттин кулпусун <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу ийгиликсиз аракет кылсаңыз, бул колдонуучу чыгарылып салынып, колдонуучунун бардык дайындары жок болот."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Телефондун кулпусун <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу ийгиликсиз аракет кылсаңыз, бул колдонуучу чыгарылып салынып, колдонуучунун бардык дайындары жок болот."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Планшеттин кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Жумуш профили чыгарылып салынып, андагы бардык дайындар жок болот."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Телефондун кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Жумуш профили чыгарылып салынып, андагы бардык дайындар жок болот."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Сиз графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин планшетиңизди бөгөттөн электрондук почтаңыз аркылуу чыгарышыңыз талап кылынат.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайра аракеттениңиз."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Сиз графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин телефонуңузду бөгөттөн электрондук почтаңыз аркылуу чыгаруу талап кылынат.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайра аракеттениңиз."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM-картанын PIN-коду туура эмес. Эми түзмөктү бөгөттөн чыгаруу үчүн байланыш операторуңузга кайрылышыңыз керек."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM-картанын PIN-коду туура эмес, сизде <xliff:g id="NUMBER_1">%d</xliff:g> аракет калды.</item>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index 3683002..3ae088b 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ກົດ \"ເມນູ\" ເພື່ອປົດລັອກ."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ເຄືອຂ່າຍຖືກລັອກ"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ບໍ່ມີຊິມກາດ"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ບໍ່ມີຊິມກາດໃນແທັບເລັດ."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ບໍ່ມີ SIM card ໃນໂທລະສັບ."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"ໃສ່ຊິມກາດ."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"ບໍ່ພົບເຫັນຊິມກາດ ຫຼືບໍ່ສາມາດອ່ານຊິມກາດໄດ້. ກະລຸນາໃສ່ຊິມກາດໃໝ່."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM card ບໍ່ສາມາດໃຊ້ໄດ້."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"ພິມລະຫັດ PIN ທີ່ມີ 4 ຫາ 8 ໂຕເລກ."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"ລະຫັດ PUK ຄວນມີຢ່າງໜ້ອຍ 8 ໂຕເລກ."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"ປ້ອນລະຫັດ PUK ທີ່ຖືກຕ້ອງຄືນໃໝ່. ການພະຍາຍາມໃສ່ຫຼາຍເທື່ອຈະເຮັດໃຫ້ຊິມກາດໃຊ້ບໍ່ໄດ້ຖາວອນ."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ລະຫັດ PIN ບໍ່ກົງກັນ"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ແຕ້ມຮູບແບບປົດລັອກຫຼາຍເກີນໄປ"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"ທ່ານພິມລະຫັດ PIN ຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. \n\nກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ວິນາທີ."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ທ່ານພິມລະຫັດຜ່ານຜິດ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. \n\nໃຫ້ລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ວິນາທີ."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ທ່ານແຕ້ມຮູບແບບປົດລັອກບໍ່ຖືກ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ວິນາທີ."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ທ່ານພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຄັ້ງ. ຫຼັງຈາກລອງບໍ່ສຳເລັດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ຄັ້ງ, ແທັບເລັດນີ້ຈະຖືກຕັ້ງຄ່າໃໝ່, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຂອງມັນ."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ທ່ານພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຄັ້ງ. ຫຼັງຈາກລອງບໍ່ສຳເລັດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ຄັ້ງ, ໂທລະສັບນີ້ຈະຖືກຕັ້ງຄ່າໃໝ່, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຂອງມັນ."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ທ່ານພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER">%d</xliff:g> ຄັ້ງ. ແທັບເລັດນີ້ຈະຖືກຕັ້ງຄ່າໃໝ່, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຂອງມັນ."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ທ່ານພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER">%d</xliff:g> ຄັ້ງ. ໂທລະສັບນີ້ຈະຖືກຕັ້ງຄ່າໃໝ່, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຂອງມັນ."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ທ່ານພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຄັ້ງ. ຫຼັງຈາກລອງບໍ່ສຳເລັດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g>ຄັ້ງ, ຜູ້ໃຊ້ນີ້ຈະຖືກເອົາອອກໄປ, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຜູ້ໃຊ້."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ທ່ານພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຄັ້ງ. ຫຼັງຈາກລອງບໍ່ສຳເລັດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ຄັ້ງ, ຜູ້ໃຊ້ນີ້ຈະຖືກເອົາອອກໄປ, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຜູ້ໃຊ້."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ທ່ານພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER">%d</xliff:g> ຄັ້ງ. ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຈະຖືກເອົາອອກໄປ, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນໂປຣໄຟລ໌."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ທ່ານພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER">%d</xliff:g> ຄັ້ງ. ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຈະຖືກເອົາອອກໄປ, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນໂປຣໄຟລ໌."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຜິດ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບໂດຍໃຊ້ອີເມວຂອງທ່ານ.\n\n ກະລຸນາລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_2">%3$d</xliff:g> ວິນາທີ."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ເທື່ອ ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍບັນຊີອີເມວ.\n\n ລອງໃໝ່ອີກຄັ້ງໃນ <xliff:g id="NUMBER_2">%3$d</xliff:g> ວິນາທີ."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ລະຫັດ PIN ຂອງ SIM ບໍ່ຖືກຕ້ອງທ່ານຕ້ອງຕິດຕໍ່ຫາຜູ່ໃຫ້ບໍລິການ ເພື່ອປົດລັອກອຸປະກອນຂອງທ່ານ."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">ລະຫັດ SIM PIN ບໍ່ຖືກຕ້ອງ, ທ່ານຍັງພະຍາຍາມໄດ້ອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ຄັ້ງ.</item>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index 49812ce..3d637f0 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Paspauskite meniu, jei norite atrakinti."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Tinklas užrakintas"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nėra SIM kortelės"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Planšetiniame kompiuteryje nėra SIM kortelės."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefone nėra SIM kortelės."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Įdėkite SIM kortelę."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Nėra SIM kortelės arba ji neskaitoma. Įdėkite SIM kortelę."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Negalima naudoti SIM kortelės."</string>
@@ -85,17 +83,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Įveskite PIN kodą, sudarytą iš 4–8 skaičių."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kodas turėtų būti sudarytas iš 8 ar daugiau skaitmenų."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Pakartotinai įveskite tinkamą PUK kodą. Pakartotinai bandant SIM kortelė bus išjungta visam laikui."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodai nesutampa"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Per daug atrakinimo piešinių bandymų"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai įvedėte PIN kodą. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai įvedėte slaptažodį. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai nupiešėte atrakinimo piešinį. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. nesėkmingai bandėte atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. šis planšetinis kompiuteris bus nustatytas iš naujo ir visi jo duomenys bus ištrinti."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. nesėkmingai bandėte atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. šis telefonas bus nustatytas iš naujo ir visi jo duomenys bus ištrinti."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"<xliff:g id="NUMBER">%d</xliff:g> kart. nesėkmingai bandėte atrakinti planšetinį kompiuterį. Šis planšetinis kompiuteris bus nustatytas iš naujo ir visi jo duomenys bus ištrinti."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"<xliff:g id="NUMBER">%d</xliff:g> kart. nesėkmingai bandėte atrakinti telefoną. Šis telefonas bus nustatytas iš naujo ir visi jo duomenys bus ištrinti."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. nesėkmingai bandėte atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. šis naudotojas bus pašalintas ir visi naudotojo duomenys bus ištrinti."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. nesėkmingai bandėte atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. šis naudotojas bus pašalintas ir visi naudotojo duomenys bus ištrinti."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -104,10 +95,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"<xliff:g id="NUMBER">%d</xliff:g> kart. nesėkmingai bandėte atrakinti planšetinį kompiuterį. Darbo profilis bus pašalintas ir visi profilio duomenys bus ištrinti."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"<xliff:g id="NUMBER">%d</xliff:g> kart. nesėkmingai bandėte atrakinti telefoną. Darbo profilis bus pašalintas ir visi profilio duomenys bus ištrinti."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai nupiešėte atrakinimo piešinį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami el. pašto paskyrą.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai nupiešėte atrakinimo piešinį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami el. pašto paskyrą.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Netinkamas SIM kortelės PIN kodas. Reikės susisiekti su operatoriumi, kad atrakintų įrenginį."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Netinkamas SIM kortelės PIN kodas. Liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymas.</item>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index 94244ac..2c24f4a 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Lai atbloķētu, nospiediet izvēlnes ikonu."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Tīkls ir bloķēts."</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nav SIM kartes."</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Planšetdatorā nav SIM kartes."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Tālrunī nav SIM kartes."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Ievietojiet SIM karti."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Nav SIM kartes, vai arī to nevar nolasīt. Ievietojiet SIM karti."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Nelietojama SIM karte."</string>
@@ -84,17 +82,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Ievadiet PIN kodu, kas sastāv no 4 līdz 8 cipariem."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kodam ir jābūt vismaz 8 ciparus garam."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Atkārtoti ievadiet pareizo PUK kodu. Ja vairākas reizes ievadīsiet to nepareizi, SIM karte tiks neatgriezeniski atspējota."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodi neatbilst."</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Pārāk daudz kombinācijas mēģinājumu"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) esat ievadījis nepareizu PIN kodu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundes(-ēm)."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) esat ievadījis nepareizu paroli.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundes(-ēm)."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) esat nepareizi uzzīmējis atbloķēšanas kombināciju.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundes(-ēm)."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt planšetdatoru. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) šis planšetdators tiks atiestatīts, kā arī visi planšetdatora dati tiks dzēsti."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt tālruni. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) šis tālrunis tiks atiestatīts, kā arī visi tālruņa dati tiks dzēsti."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt planšetdatoru. Šis planšetdators tiks atiestatīts, kā arī visi planšetdatora dati tiks dzēsti."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt tālruni. Šis tālrunis tiks atiestatīts, kā arī visi tālruņa dati tiks dzēsti."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt planšetdatoru. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) šis lietotājs tiks noņemts, kā arī visi lietotāja dati tiks dzēsti."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt tālruni. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) šis lietotājs tiks noņemts, kā arī visi lietotāja dati tiks dzēsti."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -103,10 +94,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt planšetdatoru. Darba profils tiks noņemts, kā arī visi profila dati tiks dzēsti."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt tālruni. Darba profils tiks noņemts, kā arī visi profila dati tiks dzēsti."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nepareizi norādījāt atbloķēšanas kombināciju. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) planšetdators būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundes(-ēm)."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nepareizi norādījāt atbloķēšanas kombināciju. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) tālrunis būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundes(-ēm)."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Nepareizs SIM kartes PIN kods. Lai atbloķētu ierīci, sazinieties ar mobilo sakaru operatoru."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="zero">Nepareizs SIM kartes PIN kods. Varat mēģināt vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizes.</item>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index 52528f7..d434bc4 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притиснете „Мени“ за отклучување."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежата е заклучена"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Нема SIM-картичка"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Во таблетот нема SIM-картичка."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Во телефонот нема SIM-картичка."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Вметнете SIM-картичка."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Нема SIM-картичка или не може да се прочита. Вметнете SIM-картичка."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Неупотреблива SIM-картичка."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Внесете PIN што содржи 4 - 8 броеви."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-кодот треба да содржи 8 или повеќе броеви."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Повторно внесете го точниот PUK-код. Повторните обиди трајно ќе ја оневозможат SIM-картичката."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-кодовите не се совпаѓаат"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Премногу обиди со шема"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Погрешно сте го напишале вашиот PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Погрешно сте ја напишале вашата лозинка <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Погрешно сте ја нацртале вашата шема за отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Неправилно се обидовте да го отклучите таблетот <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, таблетот ќе се ресетира, со што ќе се избришат сите негови податоци."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Неправилно се обидовте да го отклучите телефонот <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, телефонот ќе се ресетира, со што ќе се избришат сите негови податоци."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Неправилно се обидовте да го отклучите таблетот <xliff:g id="NUMBER">%d</xliff:g> пати. Овој таблет ќе се ресетира, со што ќе се избришат сите негови податоци."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Неправилно се обидовте да го отклучите телефонот <xliff:g id="NUMBER">%d</xliff:g> пати. Овој телефон ќе се ресетира, со што ќе се избришат сите негови податоци."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Неправилно се обидовте да го отклучите таблетот <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, корисникот ќе се отстрани, со што ќе се избришат сите негови податоци."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Неправилно се обидовте да го отклучите телефонот <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, корисникот ќе се отстрани, со што ќе се избришат сите податоци на корисникот."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Неправилно се обидовте да го отклучите таблетот <xliff:g id="NUMBER">%d</xliff:g> пати. Работниот профил ќе се отстрани, со што ќе се избришат сите податоци на профилот."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Неправилно се обидовте да го отклучите телефонот <xliff:g id="NUMBER">%d</xliff:g> пати. Работниот профил ќе се отстрани, со што ќе се избришат сите податоци на профилот."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Погрешно сте ја употребиле вашата шема на отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, ќе побараме да го отклучите таблетот со сметка на е-пошта.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Погрешно сте ја употребиле вашата шема на отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, ќе побараме да го отклучите телефонот со сметка на е-пошта.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Погрешен PIN-код за SIM, сега мора да контактирате со вашиот оператор за да го отклучите уредот."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Погрешен PIN-код за SIM, ви преостанува уште <xliff:g id="NUMBER_1">%d</xliff:g> обид.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index 5f3a8ca..3992e17 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"അൺലോക്കുചെയ്യാൻ മെനു അമർത്തുക."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"നെറ്റ്വർക്ക് ലോക്കുചെയ്തു"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"സിം കാർഡില്ല"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ടാബ്ലെറ്റിൽ സിം കാർഡൊന്നുമില്ല."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ഫോണിൽ സിം കാർഡൊന്നുമില്ല."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"ഒരു സിം കാർഡ് ഇടുക."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"സിം കാർഡ് കാണുന്നില്ല, അല്ലെങ്കിൽ റീഡുചെയ്യാനായില്ല. ഒരു സിം കാർഡ് ഇടുക."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"ഉപയോഗയോഗ്യമല്ലാത്ത സിം കാർഡ്."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 മുതൽ 8 വരെ അക്കങ്ങളുള്ള ഒരു പിൻ ടൈപ്പുചെയ്യുക."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK കോഡിൽ 8 അല്ലെങ്കിൽ അതിലധികം സംഖ്യകൾ ഉണ്ടായിരിക്കണം."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"ശരിയായ PUK കോഡ് വീണ്ടും നൽകുക. ആവർത്തിച്ചുള്ള ശ്രമങ്ങൾ സിം ശാശ്വതമായി പ്രവർത്തനരഹിതമാക്കും."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"പിൻ കോഡുകൾ പൊരുത്തപ്പെടുന്നില്ല"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"വളരെയധികം പാറ്റേൺ ശ്രമങ്ങൾ"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ പിൻ തെറ്റായി ടൈപ്പുചെയ്തു. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> സെക്കന്റിനുശേഷം വീണ്ടും ശ്രമിക്കുക."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ നിങ്ങളുടെ പാസ്വേഡ് തെറ്റായി ടൈപ്പുചെയ്തു. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> സെക്കന്റിനുശേഷം വീണ്ടും ശ്രമിക്കുക."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ അൺലോക്ക് പാറ്റേൺ തെറ്റായി വരച്ചു. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> സെക്കന്റിനുശേഷം വീണ്ടും ശ്രമിക്കുക."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി ടാബ്ലെറ്റ് അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, ഈ ടാബ്ലെറ്റ് റീസെറ്റുചെയ്യപ്പെടുകയും, അതുവഴി അതിലെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി ഫോൺ അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ ഈ ഫോൺ റീസെറ്റുചെയ്യപ്പെടുകയും, അതുവഴി അതിലെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി ടാബ്ലെറ്റ് അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. ഈ ഫോൺ റീസെറ്റുചെയ്യപ്പെടുകയും, അതുവഴി അതിലെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി ഫോൺ അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. ഈ ഫോൺ റീസെറ്റുചെയ്യപ്പെടുകയും, അതുവഴി അതിലെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി ടാബ്ലെറ്റ് അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ ഈ ഉപയോക്താവിനെ നീക്കം ചെയ്യുകയും, അതുവഴി ഉപയോക്താവിന്റെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി ഫോൺ അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ ഈ ഉപയോക്താവിനെ നീക്കം ചെയ്യുകയും, അതുവഴി ഉപയോക്താവിന്റെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി ടാബ്ലെറ്റ് അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. ഔദ്യോഗിക പ്രൊഫൈൽ നീക്കംചെയ്യപ്പെടുകയും, അതുവഴി എല്ലാ പ്രൊഫൈൽ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി ഫോൺ അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. ഔദ്യോഗിക പ്രൊഫൈൽ നീക്കംചെയ്യപ്പെടുകയും, അതുവഴി എല്ലാ പ്രൊഫൈൽ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി അൺലോക്ക് പാറ്റേൺ വരച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, ഒരു ഇമെയിൽ അക്കൗണ്ടുപയോഗിച്ച് ടാബ്ലെറ്റ് അൺലോക്കുചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> സെക്കന്റ് കഴിഞ്ഞ് വീണ്ടും ശ്രമിക്കുക."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി അൺലോക്ക് പാറ്റേൺ വരച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, ഒരു ഇമെയിൽ അക്കൗണ്ടുപയോഗിച്ച് ഫോൺ അൺലോക്കുചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> സെക്കന്റ് കഴിഞ്ഞ് വീണ്ടും ശ്രമിക്കുക."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"സിം പിൻ കോഡ് തെറ്റാണ്, നിങ്ങളുടെ ഉപകരണം അൺലോക്കുചെയ്യാൻ ഇനി നിങ്ങളുടെ കാരിയറുമായി ബന്ധപ്പെടണം."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">സിം പിൻ കോഡ് തെറ്റാണ്, നിങ്ങൾക്ക് <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു.</item>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index 6eda5d8..ba80daf 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Түгжээг тайлах бол цэсийг дарна уу."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Сүлжээ түгжигдсэн"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM карт алга"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Таблетад SIM карт алга."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Утсанд SIM карт алга."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM картыг оруулна уу."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM карт байхгүй, эсвэл унших боломжгүй байна. SIM карт оруулна уу."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Ашиглах боломжгүй SIM карт байна."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4-8 тооноос бүтэх ПИН-г оруулна уу."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK код 8-с цөөнгүй тооноос бүтнэ."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Зөв PUK кодыг дахин оруулна уу. Олон удаагийн оролдлого нь SIM-г хүчингүй болгоно."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ПИН код тохирохгүй байна"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Загварыг хэт олон удаа буруу оруулсан байна"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Та ПИН кодоо <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Та нууц үгээ <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Та тайлах хээг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Та таблетын түгжээг тайлах оролдлогыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу хийлээ. Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд энэ таблетыг шинэчлэх бөгөөд бүх өгөгдөл нь устах болно."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Та утасны түгжээг тайлах оролдлогыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу хийлээ.Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд энэ утсыг шинэчлэх бөгөөд бүх өгөгдөл нь устах болно."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Та таблетын түгжээг тайлах оролдлогыг <xliff:g id="NUMBER">%d</xliff:g> удаа буруу хийлээ. Энэ таблетыг шинэчлэх бөгөөд ингэснээр бүх өгөгдөл нь устах болно."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Та утасны түгжээг тайлах оролдлогыг <xliff:g id="NUMBER">%d</xliff:g> удаа буруу хийлээ. Энэ утсыг шинэчлэх бөгөөд ингэснээр бүх өгөгдөл нь устах болно."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Та таблетын түгжээг тайлах оролдлогыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу хийсэн байна. Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд энэ хэрэглэгчийг устгах бөгөөд ингэснээр хэрэглэгчийн бүх өгөгдөл устах болно."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Та утасны түгжээг тайлах оролдлогыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу хийсэн байна. Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд энэ хэрэглэгчийг устгах бөгөөд ингэснээр хэрэглэгчийн бүх өгөгдөл устах болно."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Та таблетын түгжээг тайлах оролдогыг <xliff:g id="NUMBER">%d</xliff:g> удаа буруу хийсэн байна. Ажлын профайлыг устгах бөгөөд ингэснээр профайлын бүх өгөгдөл устах болно."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Та утасны түгжээг тайлах оролдлогыг <xliff:g id="NUMBER">%d</xliff:g> удаа буруу хийлээ. Ажлын профайлыг устгах бөгөөд ингэснээр профайлын бүх өгөгдлийг устгах болно."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Та түгжээ тайлах загварыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд таблетынхаа түгжээг имэйл бүртгэлээрээ тайлах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Та түгжээ тайлах загварыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд утасныхаа түгжээг имэйл бүртгэлээрээ тайлах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM-н ПИН кодыг буруу оруулсан тул та төхөөрөмжийнхөө түгжээг тайлахын тулд оператор компанитайгаа холбогдоно уу."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM-н ПИН код буруу байна. Танд <xliff:g id="NUMBER_1">%d</xliff:g> оролдлого үлдлээ.</item>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 1c9ef54..9d46fb9 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"अनलॉक करण्यासाठी मेनू दाबा."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लॉक केले"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"सिम कार्ड नाही"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"टॅबलेटमध्ये सिम कार्ड नाही."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"फोनमध्ये सिम कार्ड नाही."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"सिम कार्ड घाला."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"सिम कार्ड गहाळ झाले आहे किंवा ते वाचनीय नाही. सिम कार्ड घाला."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"निरुपयोगी सिम कार्ड."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 ते 8 अंकांचा पिन टाईप करा."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK कोड 8 अंकी किंवा त्यापेक्षा अधिकचा असावा."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"योग्य PUK कोड पुन्हा एंटर करा. पुनःपुन्हा प्रयत्न करणे सिम कायमचे अक्षम करेल."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"पिन कोड जुळत नाहीत"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"खूप जास्त पॅटर्न प्रयत्न"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"तुम्ही तुमचा PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"तुम्ही तुमचा पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने काढला. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"तुम्ही टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, हे टॅबलेट रीसेट केला जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, हा फोन रीसेट केला जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"तुम्ही टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. हे टॅबलेट रीसेट केले जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. हा फोन रीसेट केला जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"तुम्ही टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, या वापरकर्त्याला काढले जाईल, जे सर्व वापरकर्ता डेटा हटवेल."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, या वापरकर्त्याला काढले जाईल, जे सर्व वापरकर्ता डेटा हटवेल."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"तुम्ही टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. कार्य प्रोफाइल काढली जाईल, जे सर्व प्रोफाइल डेटा हटवेल."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. कार्य प्रोफाइल काढली जाईल, जे सर्व प्रोफाइल डेटा हटवेल."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून तुमचा टॅब्लेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून तुमचा फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"सिम पिन कोड चुकीचा आहे तुम्ही आता तुमचे डिव्हाइस अनलॉक करण्यासाठी तुमच्या वाहकाशी संपर्क साधावा."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">चुकीचा सिम पिन कोड, तुमच्याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहेत.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index d8b63da..7c8e1b8 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tekan Menu untuk membuka kunci."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rangkaian dikunci"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Tiada kad SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Tiada kad SIM dalam tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Tiada kad SIM dalam telefon."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Masukkan kad SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Kad SIM tiada atau tidak dapat dibaca. Sila masukkan kad SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Kad SIM tidak boleh digunakan."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Taipkan PIN yang mengandungi 4 hingga 8 nombor."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Kod PUK seharusnya 8 nombor atau lebih."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Masukkan semula kod PUK yang betul. Percubaan berulang akan melumpuhkan SIM secara kekal."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kod PIN tidak sepadan"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Terlalu banyak percubaan melukis corak"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Anda telah tersilap taip PIN sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> saat."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Anda telah tersilap taip kata laluan sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> saat."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> saat."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Anda telah salah membuka kunci tablet sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, tablet ini akan ditetapkan semula sekali gus memadamkan semua data."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Anda telah salah membuka kunci telefon sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, telefon ini akan ditetapkan semula sekali gus memadamkan semua data."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Anda telah salah membuka kunci tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet ini akan ditetapkan semula sekali gus memadamkan semua data."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Anda telah salah membuka kunci telefon sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Telefon ini akan ditetapkan semula sekali gus memadamkan semua data."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Anda telah salah membuka kunci tablet sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, pengguna ini akan dialih keluar sekali gus memadamkan semua data pengguna."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Anda telah salah membuka kunci telefon sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, pengguna ini akan dialih keluar sekali gus memadamkan semua data pengguna."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Anda telah salah membuka kunci tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Profil kerja ini akan dialih keluar sekali gus memadamkan semua data profil."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Anda telah salah membuka kunci telefon sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Profil kerja ini akan dialih keluar sekali gus memadamkan semua data profil."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, anda akan diminta membuka kunci tablet anda menggunakan akaun e-mel.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, anda akan diminta membuka kunci telefon anda menggunakan akaun e-mel.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Kod PIN SIM salah. Anda mesti menghubungi pembawa anda untuk membuka kunci peranti."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Kod PIN SIM salah, tinggal <xliff:g id="NUMBER_1">%d</xliff:g> percubaan.</item>
diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml
index 83f9b7e..19a5c25 100644
--- a/packages/SystemUI/res-keyguard/values-my/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-my/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"မီနူးကို နှိပ်၍ လော့ခ်ဖွင့်ပါ။"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ကွန်ရက်ကို လော့ခ်ချထားသည်"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ဆင်းမ်ကဒ် မရှိပါ"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"တက်ဘလက်ထဲတွင် ဆင်းမ်ကဒ် မရှိပါ။"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ဖုန်းထဲတွင် ဆင်းမ်ကဒ် မရှိပါ။"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"ဆင်းမ်ကဒ် ထည့်ပါ။"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"ဆင်းမ်ကဒ်မရှိပါ သို့မဟုတ် အသုံးပြု၍မရပါ။ ဆင်းမ်ကဒ်တစ်ခု ထည့်ပါ။"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"အသုံးပြု၍ မရတော့သော ဆင်းမ်ကဒ်။"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"ဂဏန်း ၄ လုံးမှ ၈ လုံးအထိ ရှိသော ပင်နံပါတ်ကို ထည့်ပါ။"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"ပင်နံပါတ် ပြန်ဖွင့်သည့်ကုဒ်သည် ဂဏန်း ၈ လုံးနှင့် အထက် ဖြစ်ရပါမည်။"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"မှန်ကန်သည့် ပင်နံပါတ် ပြန်ဖွင့်သည့်ကုဒ်ကို ပြန်ထည့်ပါ။ ထပ်ခါထပ်ခါမှားယွင်းနေလျှင် ဆင်းမ်ကဒ်ကို အပြီးအပိုင် ပိတ်လိုက်ပါမည်။"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ပင်နံပါတ် ကိုက်ညီမှုမရှိပါ"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ပုံစံထည့်သွင်းရန် ကြိုးစားသည့် အကြိမ်အရေအတွက် အလွန်များနေပါပြီ"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"သင်သည် ပင်နံပါတ်ကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ်မှားယွင်းစွာ ထည့်ခဲ့ပါသည်။ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"သင်သည် စကားဝှက်ကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ်မှားယွင်းစွာ ထည့်ခဲ့ပါသည်။ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"သင်သည် ပုံစံကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ်မှားယွင်းစွာ ဆွဲခဲ့ပါသည်။ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"တက်ဘလက်ကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းခဲ့လျှင် ဤတက်ဘလက်ကို ပြင်ဆင်သတ်မှတ်လိုက်မည် ဖြစ်ပြီး ၎င်းအတွင်းရှိ ဒေတာများအားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ဖုန်းကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းခဲ့လျှင် ဤဖုန်းကို ပြင်ဆင်သတ်မှတ်လိုက်မည် ဖြစ်ပြီး ၎င်းအတွင်းရှိ ဒေတာများအားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"တက်ဘလက်ကို <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ ဤတက်ဘလက်ကို ပြင်ဆင်သတ်မှတ်လိုက်မည် ဖြစ်ပြီး ၎င်းအတွင်းရှိ ဒေတာများအားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ဖုန်းကို <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ ဤဖုန်းကို ပြင်ဆင်သတ်မှတ်လိုက်မည် ဖြစ်ပြီး ၎င်းအတွင်းရှိ ဒေတာများအားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"တက်ဘလက်ကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းခဲ့လျှင် ဤအသုံးပြုသူကို ဖယ်ရှားလိုက်မည်ဖြစ်ပြီး အသုံးပြုသူဒေတာများ အားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ဖုန်းကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းသွားလျှင် ဤအသုံးပြုသူကို ဖယ်ရှားလိုက်မည်ဖြစ်ပြီး အသုံးပြုသူဒေတာများ အားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"တက်ဘလက်ကို <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ အလုပ်ပရိုဖိုင်ကို ဖယ်ရှားလိုက်မည်ဖြစ်ပြီး ပရိုဖိုင်ဒေတာများ အားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ဖုန်းကို <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ အလုပ်ပရိုဖိုင်ကို ဖယ်ရှားလိုက်မည်ဖြစ်ပြီး ပရိုဖိုင်ဒေတာများ အားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"သင်သည် သင်၏ လော့ခ်ဖွင့်ခြင်းပုံစံကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ ဆွဲခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းပြီးသည့်နောက်တွင် သင့်အီးမေးလ်အကောင့်အား အသုံးပြု၍ တက်ဘလက်ကို လော့ခ်ဖွင့်ရန် တောင်းဆိုသွားပါမည်။\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"သင်သည် သင်၏ လော့ခ်ဖွင့်ခြင်းပုံစံကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ ဆွဲခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းပြီးသည့်နောက်တွင် သင့်အီးမေးလ်အကောင့်အား အသုံးပြု၍ ဖုန်းကို လော့ခ်ဖွင့်ရန် တောင်းဆိုသွားပါမည်။\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ဆင်းမ်ကဒ်ပင်နံပါတ် မှားယွင်းနေသောကြောင့် ယခုအခါ သင့်စက်ပစ္စည်းအား လော့ခ်ဖွင့်ရန် ဝန်ဆောင်မှုပေးသူကို ဆက်သွယ်ရပါမည်။"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">ဆင်းမ်ပင်နံပါတ် မှန်ကန်မှုမရှိပါ။ <xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ် စမ်းသပ်ခွင့်ရှိပါသေးသည်။</item>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index e766d59..d5aa0e1 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Trykk på menyknappen for å låse opp."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Nettverket er låst"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM-kort mangler"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nettbrettet mangler SIM-kort."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefonen mangler SIM-kort."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Sett inn et SIM-kort."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM-kort mangler eller er uleselig. Sett inn et SIM-kort."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Ubrukelig SIM-kort."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Skriv inn en PIN-kode på fire til åtte sifre."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-koden skal være på åtte eller flere sifre."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Skriv inn den riktige PUK-koden på nytt. Gjentatte forsøk deaktiverer SIM-kortet permanent."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-kodene stemmer ikke overens"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"For mange forsøk på tegning av mønster"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Du har oppgitt feil PIN-kode <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Du har tastet inn passordet ditt feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Du har tegnet opplåsningsmønsteret ditt feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Du har gjort feil i forsøket på å låse opp nettbrettet <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Nettbrettet tilbakestilles etter <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk, noe som sletter alle dataene på nettbrettet."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Du har gjort feil i forsøket på å låse opp telefonen <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Telefonen tilbakestilles etter <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk, noe som sletter alle dataene på telefonen."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Du har gjort feil i forsøket på å låse opp nettbrettet <xliff:g id="NUMBER">%d</xliff:g> ganger. Dette nettbrettet blir tilbakestilt, og alle dataene blir slettet."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Du har gjort feil i forsøket på å låse opp telefonen <xliff:g id="NUMBER">%d</xliff:g> ganger. Denne telefonen blir tilbakestilt, og alle dataene blir slettet."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Du har gjort feil i forsøket på å låse opp nettbrettet <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Brukeren fjernes etter <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk, noe som sletter alle brukerdataene."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Du har gjort feil i forsøket på å låse opp telefonen <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Brukeren fjernes etter <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk, noe som sletter alle brukerdataene."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Du har gjort feil i forsøket på å låse opp nettbrettet <xliff:g id="NUMBER">%d</xliff:g> ganger. Jobbprofilen blir fjernet, og alle profildataene blir slettet."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Du har gjort feil i forsøket på å låse opp telefonen <xliff:g id="NUMBER">%d</xliff:g> ganger. Jobbprofilen blir fjernet, og alle profildataene blir slettet."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Du har tegnet opplåsingsmønsteret feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> feil forsøk blir du bedt om å låse opp nettbrettet via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Du har tegnet opplåsingsmønsteret feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> feil forsøk blir du bedt om å låse opp telefonen via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Feil PIN-kode for SIM-kortet. Du må nå kontakte operatøren din for å låse opp enheten."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Feil PIN-kode for SIM-kortet. Du har <xliff:g id="NUMBER_1">%d</xliff:g> forsøk igjen.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index 4f1ea2a..763dc03 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"अनलक गर्न मेनु थिच्नुहोस्।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लक भएको छ"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM कार्ड छैन"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ट्याब्लेटमा SIM कार्ड छैन।"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"फोनमा SIM कार्ड छैन।"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM कार्ड हाल्नुहोस्"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM कार्ड हालिएको छैन वा पढ्न योग्य छैन। SIM कार्ड हाल्नुहोस्।"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM कार्ड काम नलाग्ने भएको छ।"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"४ देखि ८ वटा नम्बर भएको एउटा PIN टाइप गर्नुहोस्।"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK कोड ८ वा सो भन्दा बढी नम्बरको हुनु पर्छ।"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"PUK कोड पुन: प्रविष्टि गर्नुहोस्। पटक-पटकको प्रयासले SIM सदाका लागि असक्षम हुनेछ।"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN कोडहरू मिलेनन्"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"अत्यन्त धेरै ढाँचा कोर्ने प्रयासहरू"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले आफ्नो PIN प्रविष्ट गर्नुभएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो गलत पासवर्ड प्रविष्ट गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले आफ्नो अनलक ढाँचा कोर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यो ट्याब्लेट यसमा भएका सबै डेटा मेटिने गरी रिसेट हुनेछ।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यो फोन यसमा भएका सबै डेटा मेटिने गरी रिसेट हुनेछ।"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। यो ट्याब्लेट यसमा भएका सबै डेटा मेटिने गरी रिसेट हुनेछ।"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। यो फोन यसमा भएका सबै डेटा मेटिने गरी रिसेट हुनेछ।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यस प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यस प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"तपाईं <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। कार्य प्रोफाइललाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। कार्य प्रोफाइललाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो अनलक गर्ने ढाँचा गलत रूपमा कोर्नुभयो। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, तपाईंलाई एउटा इमेल खाता प्रयोग गरेर आफ्नो ट्याब्लेट अनलक गर्न आग्रह गरिनेछ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो अनलक गर्ने ढाँचा गलत रूपमा कोर्नुभयो। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, तपाईंलाई एउटा इमेल खाता प्रयोग गरेर आफ्नो फोन अनलक गर्न आग्रह गरिनेछ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM को PIN कोड गलत छ। तपाईंले अब आफ्नो यन्त्र खोल्न आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नै पर्ने हुन्छ।"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM को PIN कोड गलत छ, तपाईं अझै <xliff:g id="NUMBER_1">%d</xliff:g> पटक प्रयास गर्न सक्नुहुन्छ।</item>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 16b3425..953e32d 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Druk op Menu om te ontgrendelen."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Netwerk vergrendeld"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Geen simkaart"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Geen simkaart in tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Geen simkaart in telefoon."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Plaats een simkaart."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"De simkaart ontbreekt of kan niet worden gelezen. Plaats een simkaart."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Onbruikbare simkaart."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Geef een pincode van vier tot acht cijfers op."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"De pukcode is minimaal acht cijfers lang."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Geef de juiste pukcode opnieuw op. Bij herhaalde pogingen wordt de simkaart definitief uitgeschakeld."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Pincodes komen niet overeen"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Te veel patroonpogingen"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Je hebt je pincode <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getypt. \n\nProbeer het over <xliff:g id="NUMBER_1">%2$d</xliff:g> seconden opnieuw."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Je hebt je wachtwoord <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getypt. \n\nProbeer het over <xliff:g id="NUMBER_1">%2$d</xliff:g> seconden opnieuw."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. \n\nProbeer het over <xliff:g id="NUMBER_1">%2$d</xliff:g> seconden opnieuw."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Je hebt <xliff:g id="NUMBER_0">%1$d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt deze tablet gereset, waardoor alle gegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Je hebt <xliff:g id="NUMBER_0">%1$d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt deze telefoon gereset, waardoor alle gegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Deze tablet wordt gereset, waardoor alle gegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Deze telefoon wordt gereset, waardoor alle gegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Je hebt <xliff:g id="NUMBER_0">%1$d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt deze gebruiker verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Je hebt <xliff:g id="NUMBER_0">%1$d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt deze gebruiker verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Het werkprofiel wordt verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Het werkprofiel wordt verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt je gevraagd je tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt je gevraagd je telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Onjuiste pincode voor simkaart. Je moet nu contact opnemen met je provider om je apparaat te ontgrendelen."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Onjuiste pincode voor simkaart. Je hebt nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over.</item>
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index b2e8957..32738d8c 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ଅନଲକ୍ କରିବା ପାଇଁ ମେନୁକୁ ଦବାନ୍ତୁ।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ନେଟୱର୍କକୁ ଲକ୍ କରାଯାଇଛି"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"କୌଣସି SIM କାର୍ଡ ନାହିଁ"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ଟାବଲେଟ୍ରେ କୌଣସି SIM କାର୍ଡ ନାହିଁ।"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ଫୋନରେ କୌଣସି SIM କାର୍ଡ ନାହିଁ।"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"ଗୋଟିଏ SIM କାର୍ଡ ଭର୍ତ୍ତି କରନ୍ତୁ।"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM କାର୍ଡ ନାହିଁ କିମ୍ବା ଖରାପ ଅଛି। SIM କାର୍ଡ ଭର୍ତ୍ତି କରନ୍ତୁ।"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM କାର୍ଡଟିକୁ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ।"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 ରୁ 8 ନମ୍ବର ବିଶିଷ୍ଟ ଏକ PIN ଟାଇପ୍ କରନ୍ତୁ।"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK କୋଡ୍ରେ 8ଟି କିମ୍ବା ଅଧିକ ନମ୍ବର ରହିଥାଏ।"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"ଠିକ୍ PUK କୋଡ୍ ପୁଣି ଲେଖନ୍ତୁ। ବାରମ୍ବାର ପ୍ରୟାସ କଲେ SIM କାର୍ଡ ସ୍ଥାୟୀ ରୂପେ ଅକ୍ଷମ ହୋଇଯିବ।"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN କୋଡ୍ ମେଳ ହେଉନାହିଁ"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ଅନେକ ପାଟର୍ନ ପ୍ରୟାସ"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"ଆପଣଙ୍କ PIN ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଟାଇପ୍ କରିଛନ୍ତି। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ଆପଣଙ୍କ ପାସ୍ୱର୍ଡକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଟାଇପ୍ କରିଛନ୍ତି। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ଆପଣଙ୍କ ଲକ୍ ଖୋଲିବା ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ଆପଣ ଟାବଲେଟକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଭୁଲ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ଏହି ଟାବଲେଟଟି ରିସେଟ୍ ହୋଇଯିବ, ଯାହାଦ୍ୱାରା ଏହାର ସମସ୍ତ ଡାଟା ଲିଟ୍ ହୋଇଯିବ।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ଆପଣ ଫୋନକୁ ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଭୁଲ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ଏହି ଫୋନଟି ରିସେଟ୍ ହୋଇଯିବ, ଯାହାଦ୍ୱାରା ଏହାର ସମସ୍ତ ଡାଟା ଲିଟ୍ ହୋଇଯିବ।"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g> ଥର ଭୁଲ୍ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ଟାବଲେଟକୁ ରିସେଟ୍ କରାଯିବ, ଯାହାଦ୍ୱାରା ଏହାର ସମସ୍ତ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ଆପଣ ଫୋନଟି ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ୍ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ଫୋନ୍ ରିସେଟ୍ କରାଯିବ, ଯାହା ଦ୍ୱାରା ଏହାର ସମସ୍ତ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ଆପଣ ଟାବଲେଟ୍ଟିକୁ ଅନଲକ୍ କରିବା ପାଇଁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଚେଷ୍ଟା କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ୱାର୍କ ପ୍ରୋଫାଇଲ୍କୁ ବାହାର କରିଦିଆଯିବ ଏବଂ ଏହା ଦ୍ୱାରା ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ଆପଣ ଫୋନଟି ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ଏହି ୟୁଜରଙ୍କୁ ବାହାର କରିଦିଆଯିବ ଏବଂ ଏହାଦ୍ୱାରା ସମସ୍ତ ୟୁଜର୍ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g> ଭୁଲ୍ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। କାର୍ଯ୍ୟ ପ୍ରୋଫାଇଲ୍ ବାହାର କରିଦିଆଯିବ, ଯାହାଦ୍ୱାରା ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ଆପଣ ଫୋନଟି ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ୍ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ୱର୍କ ପ୍ରୋଫାଇଲ୍ ବାହାର କରିଦିଆଯିବ, ଯାହା ଦ୍ୱାରା ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ଆପଣଙ୍କ ଅନଲକ୍ ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଟି ଭୁଲ ପ୍ରୟାସ ପରେ ଏକ ଇମେଲ୍ ଆକାଉଣ୍ଟ ବ୍ୟବହାର କରି ନିଜ ଟାବଲେଟକୁ ଅନଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ଆପଣଙ୍କ ଅନଲକ୍ ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଟି ଭୁଲ ପ୍ରୟାସ ପରେ ଏକ ଇମେଲ୍ ଆକାଉଣ୍ଟ ବ୍ୟବହାର କରି ନିଜ ଫୋନକୁ ଅନଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ଭୁଲ SIM PIN କୋଡ୍, ଆପଣଙ୍କ ଡିଭାଇସକୁ ଅନଲକ୍ କରିବା ପାଇଁ ଏବେ ହିଁ ନିଜ କେରିଅର୍ଙ୍କ ସହ ସମ୍ପର୍କ କରନ୍ତୁ।"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">ଭୁଲ SIM PIN କୋଡ୍, ଆପଣଙ୍କର ଆଉ <xliff:g id="NUMBER_1">%d</xliff:g>ଟି ପ୍ରୟାସ ବାକି ରହିଛି।</item>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index 5e68530..c53f42f 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ਅਣਲਾਕ ਕਰਨ ਲਈ \"ਮੀਨੂ\" ਦਬਾਓ।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ਨੈੱਟਵਰਕ ਲਾਕ ਕੀਤਾ ਗਿਆ"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ਕੋਈ ਸਿਮ ਕਾਰਡ ਨਹੀਂ"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ਟੈਬਲੈੱਟ ਵਿੱਚ ਕੋਈ ਸਿਮ ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ।"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ਫ਼ੋਨ ਵਿੱਚ ਕੋਈ ਸਿਮ ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ।"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"ਇੱਕ SIM ਕਾਰਡ ਪਾਓ।"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ ਜਾਂ ਪੜ੍ਹਨਯੋਗ ਨਹੀਂ ਹੈ। ਇੱਕ SIM ਕਾਰਡ ਪਾਓ।"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"ਨਾ-ਵਰਤਣਯੋਗ SIM ਕਾਰਡ।"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"ਕੋਈ ਪਿੰਨ ਟਾਈਪ ਕਰੋ ਜੋ 4 ਤੋਂ 8 ਨੰਬਰਾਂ ਦਾ ਹੋਵੇ।"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK ਕੋਡ 8 ਜਾਂ ਵੱਧ ਨੰਬਰਾਂ ਦਾ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"ਸਹੀ PUK ਕੋਡ ਮੁੜ-ਦਾਖਲ ਕਰੋ। ਬਾਰ-ਬਾਰ ਕੀਤੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ ਸਿਮ ਨੂੰ ਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਕਰ ਦੇਣਗੀਆਂ।"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ਪਿੰਨ ਕੋਡ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਪੈਟਰਨ ਕੋਸ਼ਿਸ਼ਾਂ"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"ਤੁਸੀਂ ਆਪਣਾ ਪਿੰਨ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ।\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਉਲੀਕਿਆ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਹ ਟੈਬਲੈੱਟ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਹ ਫ਼ੋਨ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਇਹ ਟੈਬਲੈੱਟ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਇਹ ਫ਼ੋਨ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਸਾਰਾ ਵਰਤੋਂਕਾਰ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਸਾਰਾ ਵਰਤੋਂਕਾਰ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਸਾਰਾ ਪ੍ਰੋਫਾਈਲ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਸਾਰਾ ਪ੍ਰੋਫਾਈਲ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਉਲੀਕਿਆ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਵੇਗਾ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫ਼ੋਨ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ਗਲਤ ਸਿਮ ਪਿੰਨ ਕੋਡ, ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਹੁਣ ਤੁਹਾਨੂੰ ਲਾਜ਼ਮੀ ਤੌਰ \'ਤੇ ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰਨਾ ਚਾਹੀਦਾ ਹੈ।"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">ਗਲਤ ਸਿਮ ਪਿੰਨ ਕੋਡ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।</item>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index c9752b9..e3d7878 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Naciśnij Menu, aby odblokować."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Sieć zablokowana"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Brak karty SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Brak karty SIM w tablecie."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Brak karty SIM w telefonie."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Włóż kartę SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Brak karty SIM lub nie można jej odczytać. Włóż kartę SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Karta SIM jest zablokowana."</string>
@@ -85,17 +83,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Wpisz kod PIN o długości od 4 do 8 cyfr."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Kod PUK musi mieć co najmniej 8 cyfr."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Wpisz poprawny kod PUK. Kolejne próby spowodują trwałe wyłączenie karty SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kody PIN nie pasują"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Zbyt wiele prób narysowania wzoru"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> wpisałeś nieprawidłowy kod PIN. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> wpisałeś nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach tablet zostanie zresetowany, co spowoduje skasowanie wszystkich jego danych."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach telefon zostanie zresetowany, co spowoduje skasowanie wszystkich jego danych."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Tablet zostanie zresetowany, co spowoduje skasowanie wszystkich jego danych."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Telefon zostanie zresetowany, co spowoduje skasowanie wszystkich jego danych."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach użytkownik zostanie usunięty, co spowoduje skasowanie wszystkich danych użytkownika."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach użytkownik zostanie usunięty, co spowoduje skasowanie wszystkich danych użytkownika."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -104,10 +95,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Profil służbowy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Profil służbowy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Nieprawidłowy kod PIN karty SIM. Musisz teraz skontaktować się z operatorem, by odblokował Twoje urządzenie."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="few">Nieprawidłowy kod PIN karty SIM. Masz jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> próby.</item>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
index 19645c0..b74aea9 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pressione Menu para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sem chip"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Não há um chip no tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Não há um chip no smartphone."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insira um chip."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"O chip não foi inserido ou não é possível lê-lo. Insira um chip."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Chip inutilizável."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Digite um PIN com 4 a 8 números."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"O código PUK deve ter oito números ou mais."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Introduza novamente o código PUK correto. Muitas tentativas malsucedidas desativarão permanentemente o chip."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Os códigos PIN não coincidem"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Muitas tentativas de padrão"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este smartphone será redefinido, o que excluirá todos os dados dele."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este smartphone será redefinido, o que excluirá todos os dados dele."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este tablet será redefinido, o que excluirá todos os dados dele."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este smartphone será redefinido, o que excluirá todos os dados dele."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este usuário será removido, o que excluirá todos os dados do usuário."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este usuário será removido, o que excluirá todos os dados do usuário."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Código PIN do chip incorreto. Entre em contato com a operadora para desbloquear o dispositivo."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Código PIN do chip incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>.</item>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index be3ca3e..e8600c8 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Prima Menu para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nenhum cartão SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nenhum cartão SIM no tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Nenhum cartão SIM no telemóvel."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insira um cartão SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"O cartão SIM está em falta ou não é legível. Insira um cartão SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Cartão SIM inutilizável."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Introduza um PIN com 4 a 8 números."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"O código PUK deve ter 8 ou mais números."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Volte a introduzir o código PUK correto. Demasiadas tentativas consecutivas irão desativar permanentemente o cartão SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Os códigos PIN não coincidem"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Demasiadas tentativas para desenhar o padrão"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Introduziu o PIN incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Introduziu a palavra-passe incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Desenhou a sua padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, este tablet será reposto, o que eliminará todos os dados do mesmo."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, este telemóvel será reposto, o que eliminará todos os dados do mesmo."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. Este tablet será reposto, o que eliminará todos os dados do mesmo."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes. Este telemóvel será reposto, o que eliminará todos os dados do mesmo."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, este utilizador será removido, o que eliminará todos os dados do mesmo."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, este utilizador será removido, o que eliminará todos os dados do mesmo."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que eliminará todos os dados do mesmo."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que eliminará todos os dados do mesmo."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Desenhou o padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Desenhou o padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Código PIN do cartão SIM incorreto. Tem de contactar o seu operador para desbloquear o dispositivo."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Código PIN do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas.</item>
diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml
index 19645c0..b74aea9 100644
--- a/packages/SystemUI/res-keyguard/values-pt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pressione Menu para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Sem chip"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Não há um chip no tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Não há um chip no smartphone."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Insira um chip."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"O chip não foi inserido ou não é possível lê-lo. Insira um chip."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Chip inutilizável."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Digite um PIN com 4 a 8 números."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"O código PUK deve ter oito números ou mais."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Introduza novamente o código PUK correto. Muitas tentativas malsucedidas desativarão permanentemente o chip."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Os códigos PIN não coincidem"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Muitas tentativas de padrão"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este smartphone será redefinido, o que excluirá todos os dados dele."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este smartphone será redefinido, o que excluirá todos os dados dele."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este tablet será redefinido, o que excluirá todos os dados dele."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este smartphone será redefinido, o que excluirá todos os dados dele."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este usuário será removido, o que excluirá todos os dados do usuário."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este usuário será removido, o que excluirá todos os dados do usuário."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Código PIN do chip incorreto. Entre em contato com a operadora para desbloquear o dispositivo."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Código PIN do chip incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index 05d1048..f8a39f0 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Apăsați pe Meniu pentru a debloca."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rețea blocată"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Niciun card SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nu există card SIM în tabletă."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Nu există card SIM în telefon."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Introduceți un card SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Cardul SIM lipsește sau nu poate fi citit. Introduceți un card SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Card SIM inutilizabil."</string>
@@ -84,17 +82,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Introduceți un cod PIN alcătuit din 4 până la 8 cifre."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Codul PUK trebuie să aibă minimum 8 cifre."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Reintroduceți codul PUK corect. Încercările repetate vor dezactiva definitiv cardul SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Codurile PIN nu coincid"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Prea multe încercări de desenare a modelului"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Ați introdus incorect codul PIN de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori.\n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> secunde."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Ați introdus incorect parola de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> secunde."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Ați desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> secunde."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Ați efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, această tabletă va fi resetată, iar toate datele acesteia vor fi șterse."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Ați efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, acest telefon va fi resetat, iar toate datele acestuia vor fi șterse."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Această tabletă va fi resetată, iar toate datele acesteia vor fi șterse."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Acest telefon va fi resetat, iar toate datele acestuia vor fi șterse."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Ați efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, acest utilizator va fi eliminat, iar toate datele utilizatorului vor fi șterse."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Ați efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, acest utilizator va fi eliminat, iar toate datele utilizatorului vor fi șterse."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -103,10 +94,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Profilul de serviciu va fi eliminat, iar toate datele profilului vor fi șterse."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Profilul de serviciu va fi eliminat, iar toate datele profilului vor fi șterse."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Ați desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, vi se va solicita să deblocați tableta cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> secunde."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Ați desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, vi se va solicita să deblocați telefonul cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> secunde."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Codul PIN pentru cardul SIM este incorect. Contactați operatorul pentru a vă debloca dispozitivul."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="few">Codul PIN pentru cardul SIM este incorect. V-au mai rămas <xliff:g id="NUMBER_1">%d</xliff:g> încercări.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index 53ad97f..4b38fdc 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Для разблокировки нажмите \"Меню\"."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Сеть заблокирована"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Нет SIM-карты."</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Нет SIM-карты."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Нет SIM-карты."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Вставьте SIM-карту."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM-карта отсутствует или недоступна. Вставьте SIM-карту."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM-карта непригодна к использованию."</string>
@@ -85,17 +83,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Введите PIN-код (от 4 до 8 цифр)."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-код должен содержать не менее 8 цифр."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Введите правильный PUK-код. После нескольких неудачных попыток SIM-карта будет заблокирована."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-коды не совпадают."</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Слишком много попыток ввести графический ключ."</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Вы ввели неверный PIN-код несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>).\n\nПовторите попытку через <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Вы ввели неверный пароль несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>).\n\nПовторите попытку через <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Вы начертили неверный графический ключ несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>).\n\nПовторите попытку через <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Вы пытались разблокировать планшет несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи произойдет сброс настроек и все данные на устройстве будут удалены."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Вы пытались разблокировать телефон несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи произойдет сброс настроек и все данные на устройстве будут удалены."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Достигнуто максимальное количество неудачных попыток разблокировать планшет (<xliff:g id="NUMBER">%d</xliff:g>). Настройки устройства будут сброшены, а все его данные – удалены."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Достигнуто максимальное количество неудачных попыток разблокировать телефон (<xliff:g id="NUMBER">%d</xliff:g>). Настройки устройства будут сброшены, а все его данные – удалены."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Вы пытались разблокировать планшет несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи профиль пользователя и все его данные будут удалены."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Вы пытались разблокировать телефон несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи профиль пользователя и все его данные будут удалены."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -104,10 +95,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Достигнуто максимальное количество неудачных попыток разблокировать планшет (<xliff:g id="NUMBER">%d</xliff:g>). Рабочий профиль и все его данные будут удалены."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Достигнуто максимальное количество неудачных попыток разблокировать телефон (<xliff:g id="NUMBER">%d</xliff:g>). Рабочий профиль и все его данные будут удалены."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Вы ввели неверный графический ключ несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи вам будет предложено разблокировать планшет с помощью аккаунта электронной почты.\n\nПовторите попытку через <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Вы ввели неверный графический ключ несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи вам будет предложено разблокировать телефон с помощью аккаунта электронной почты.\n\nПовторите попытку через <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Неверный PIN-код. Обратитесь к оператору связи, чтобы разблокировать SIM-карту."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Неверный PIN-код. Осталась <xliff:g id="NUMBER_1">%d</xliff:g> попытка.</item>
diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml
index fe1b7e9..d646018 100644
--- a/packages/SystemUI/res-keyguard/values-si/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-si/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"අගුලු හැරීමට මෙනුව ඔබන්න."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ජාලය අගුළු දමා ඇත"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM පත නැත"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ටැබ්ලටයේ SIM පත නොමැත."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"දුරකථනය තුල SIM පතක් නැත."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM කාඩ්පතක් ඇතුළු කරන්න."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM පත නොමැත හෝ කියවිය නොහැක. SIM පතක් ඇතුලත් කරන්න."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"භාවිතා කළ නොහැකි SIM පත."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 සිට 8 දක්වා අංක සහිත PIN එකක් ටයිප් කරන්න."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK කේතය සංඛ්යා 8 ක් හෝ වැඩි විය යුතුය."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"නිවැරදි PUK කේතය නැවත ඇතුලත් කරන්න. නැවත නැවත උත්සාහ කිරීමෙන් SIM එක ස්ථිරවම අබල කරයි."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN කේත නොගැළපේ."</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"රටා උත්සාහ කිරීම් වැඩිය"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"ඔබ PIN අංකය <xliff:g id="NUMBER_0">%1$d</xliff:g> වාරයක් වැරදියට ටයිප් කොට ඇත.\n\n තත්පර <xliff:g id="NUMBER_1">%2$d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ඔබ මුරපදය වාර <xliff:g id="NUMBER_0">%1$d</xliff:g> ක් වැරදියට ටයිප්කොට ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%2$d</xliff:g> කින් නැවත උත්සහ කරන්න."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ඔබ <xliff:g id="NUMBER_0">%1$d</xliff:g> වාරයක් අගුළු ඇරීමේ රටාව වැරදියට ඇඳ ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%2$d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ඔබ ටැබ්ලට් පරිගණකය අගුළු හැරීමට <xliff:g id="NUMBER_0">%1$d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. තවත් අසාර්ථක උත්සාහයන් <xliff:g id="NUMBER_1">%2$d</xliff:g>කින් පසුව, මෙම ටැබ්ලට් පරිගණකය යළි සකසනු ඇති අතර, එය එහි සියලු දත්ත මකනු ඇත."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ඔබ දුරකථනය අගුළු හැරීමට <xliff:g id="NUMBER_0">%1$d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. තවත් අසාර්ථක උත්සාහයන් <xliff:g id="NUMBER_1">%2$d</xliff:g>කින් පසුව, මෙම දුරකථනය යළි සකසනු ඇති අතර, එය එහි සියලු දත්ත මකනු ඇත."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ඔබ ටැබ්ලට් පරිගණකය අගුළු හැරීමට <xliff:g id="NUMBER">%d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. මෙම ටැබ්ලට් පරිගණකය යළි සකසනු ඇති අතර, එය එහි සියලු පදත්ත මකනු ඇත."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ඔබ දුරකථනය අගුළු හැරීමට <xliff:g id="NUMBER">%d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. මෙම දුරකථනය යළි සකසනු ඇති අතර, එය එහි සියලු පදත්ත මකනු ඇත."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ඔබ ටැබ්ලට් පරිගණකය අගුළු හැරීමට <xliff:g id="NUMBER_0">%1$d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. තවත් අසාර්ථක උත්සාහයන් <xliff:g id="NUMBER_1">%2$d</xliff:g>කින් පසුව, මෙම පරිශීලකයා ඉවත් කරනු ඇති අතර, එය සියලු පරිශීලක දත්ත මකනු ඇත."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ඔබ දුරකථනය අගුළු හැරීමට <xliff:g id="NUMBER_0">%1$d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. තවත් අසාර්ථක උත්සාහයන් <xliff:g id="NUMBER_1">%2$d</xliff:g>කින් පසුව, මෙම පරිශීලකයා ඉවත් කරනු ඇති අතර, එය සියලු පරිශීලක දත්ත මකනු ඇත."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ඔබ ටැබ්ලට් පරිගණකය අගුළු හැරීමට <xliff:g id="NUMBER">%d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. කාර්යාල පැතිකඩ ඉවත් කරනු ඇති අතර, එය සියලු පැතිකඩ දත්ත මකනු ඇත."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ඔබ දුරකථනය අගුළු හැරීමට <xliff:g id="NUMBER">%d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. කාර්යාල පැතිකඩ ඉවත් කරනු ඇති අතර, එය සියලු පැතිකඩ දත්ත මකනු ඇත."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ඔබ අගුළු ඇරිමේ රටාව <xliff:g id="NUMBER_0">%1$d</xliff:g> වතාවක් වැරදියට ඇඳ ඇත. තවත් අසාර්ථක උත්සාහ <xliff:g id="NUMBER_1">%2$d</xliff:g> කින් පසුව, ඊ-තැපැල් ගිණුම භාවිතා කරමින් ඔබගේ ටැබ්ලටයේ අගුළු ඇරීමට ඔබට පවසනු ඇත.\n\n නැවත තත්පර <xliff:g id="NUMBER_2">%3$d</xliff:g> කින් උත්සාහ කරන්න."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%1$d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%2$d</xliff:g> න් පසුව, ඔබගේ ඊ-තැපැල් ලිපිනය භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%3$d</xliff:g> න් පසුව නැවත උත්සහ කරන්න."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"වැරදී SIM PIN කේතයකි, ඔබගේ දුරකතනයේ අඟුල හැරීමට ඔබගේ වාහකයා ඔබ දැන් සම්බන්ධ කරගත යුතුය."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">වැරදී SIM PIN කේතයකි, ඔබගේ දුරකථනයේ අඟුල හැරීමට ඔබගේ වාහකයා සම්බන්ධ කරගැනීමට පෙර ඔබ සතුව තවත් උත්සාහයන් <xliff:g id="NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත.</item>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index 27b0e8e..7be6ed2 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Odomknete stlačením tlačidla ponuky."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Sieť je zablokovaná"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Žiadna SIM karta"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"V tablete nie je žiadna SIM karta."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"V telefóne nie je žiadna SIM karta."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Vložte SIM kartu."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM karta chýba alebo sa z nej nedá čítať. Vložte SIM kartu."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM karta je nepoužiteľná."</string>
@@ -85,17 +83,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Zadajte kód PIN s dĺžkou 4 až 8 číslic."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Kód PUK musí obsahovať 8 alebo viac číslic."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Znova zadajte správny kód PUK. Opakované pokusy zakážu SIM kartu natrvalo."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kódy PIN sa nezhodujú"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Príliš veľa pokusov o nakreslenie vzoru"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Už <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste zadali nesprávny kód PIN. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Už <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste zadali nesprávne heslo. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Už <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Tablet ste sa pokúsili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne odomknúť. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) bude tento tablet obnovený a všetky údaje, ktoré sú v ňom uložené, budú odstránené."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Telefón ste sa pokúsili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne odomknúť. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) bude tento telefón obnovený a všetky údaje, ktoré sú v ňom uložené, budú odstránené."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Tablet ste sa pokúsili <xliff:g id="NUMBER">%d</xliff:g>-krát nesprávne odomknúť. Tablet bude obnovený a všetky údaje, ktoré sú v ňom uložené, budú odstránené."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Telefón ste sa pokúsili <xliff:g id="NUMBER">%d</xliff:g>-krát nesprávne odomknúť. Telefón bude obnovený a všetky údaje, ktoré sú v ňom uložené, budú odstránené."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Tablet ste sa pokúsili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne odomknúť. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) bude tento používateľ odstránený a spolu s ním všetky jeho údaje."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Telefón ste sa pokúsili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne odomknúť. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) bude tento používateľ odstránený a spolu s ním všetky jeho údaje."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -104,10 +95,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Tablet ste sa pokúsili <xliff:g id="NUMBER">%d</xliff:g>-krát nesprávne odomknúť. Pracovný profil bude odstránený spolu so všetkými údajmi."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Telefón ste sa pokúsili <xliff:g id="NUMBER">%d</xliff:g>-krát nesprávne odomknúť. Pracovný profil bude odstránený spolu so všetkými údajmi."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Už ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších <xliff:g id="NUMBER_1">%2$d</xliff:g> neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Už ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g>} s."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Nesprávny kód PIN SIM karty. Teraz musíte kontaktovať svojho operátora, aby vám odomkol zariadenie."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="few">Nesprávny kód PIN SIM karty. Zostávajú vám <xliff:g id="NUMBER_1">%d</xliff:g> pokusy.</item>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index 8f08b0b..6286d10 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Če želite odkleniti, pritisnite meni."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Omrežje je zaklenjeno"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Ni kartice SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"V tabličnem računalniku ni kartice SIM."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"V telefonu ni kartice SIM."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Vstavite kartico SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Ni kartice SIM ali je ni mogoče prebrati. Vstavite kartico SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Neuporabna kartica SIM."</string>
@@ -85,17 +83,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Vnesite kodo PIN, ki vsebuje od štiri do osem številk."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Koda PUK mora biti 8- ali večmestno število."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Znova vnesite pravilno kodo PUK. Večkratni poskusi bodo trajno onemogočili kartico SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kodi PIN se ne ujemata"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Preveč poskusov vnosa vzorca"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Kodo PIN ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat vnesli napačno. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Geslo ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat vnesli napačno. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat nepravilno narisali. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Tablični računalnik ste neuspešno poskusili odkleniti <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. Če ga neuspešno poskusite odkleniti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, bo ponastavljen in vsi podatki v njem bodo izbrisani."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Telefon ste neuspešno poskusili odkleniti <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. Če ga neuspešno poskusite odkleniti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, bo ponastavljen in vsi podatki v njem bodo izbrisani."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Tablični računalnik ste neuspešno poskusili odkleniti <xliff:g id="NUMBER">%d</xliff:g>-krat, zato bo ponastavljen, vsi podatki v njem pa bodo izbrisani."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Telefon ste neuspešno poskusili odkleniti <xliff:g id="NUMBER">%d</xliff:g>-krat, zato bo ponastavljen, vsi podatki v njem pa bodo izbrisani."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Tablični računalnik ste neuspešno poskusili odkleniti <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. Če ga neuspešno poskusite odkleniti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, bo ta uporabnik odstranjen in vsi podatki uporabnika bodo izbrisani."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Telefon ste neuspešno poskusili odkleniti <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. Če ga neuspešno poskusite odkleniti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, bo ta uporabnik odstranjen in vsi podatki uporabnika bodo izbrisani."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -104,10 +95,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Tablični računalnik ste neuspešno poskusili odkleniti <xliff:g id="NUMBER">%d</xliff:g>-krat. Delovni profil bo odstranjen in vsi podatki profila bodo izbrisani."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Telefon ste neuspešno poskusili odkleniti <xliff:g id="NUMBER">%d</xliff:g>-krat. Delovni profil bo odstranjen in vsi podatki profila bodo izbrisani."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno vnesli. Če ga neuspešno poskusite vnesti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, boste pozvani, da tablični računalnik odklenete z e-poštnim računom.\n\n Poskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno vnesli. Če ga neuspešno poskusite vnesti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, boste pozvani, da telefon odklenete z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Napačna koda PIN kartice SIM. Zdaj se boste morali za odklenitev naprave obrniti na operaterja."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Napačna koda PIN kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskus.</item>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index 1336188..3980b0e 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Shtyp \"Meny\" për të shkyçur."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rrjeti është i kyçur"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Nuk ka kartë SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nuk ka kartë SIM në tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Në telefon nuk ka kartë SIM."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Fut një kartë SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Karta SIM mungon ose është e palexueshme. Fut një kartë të re SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Kartë SIM është e papërdorshme."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Shkruaj një PIN me 4 deri në 8 numra."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Kodi PUK duhet të jetë me 8 numra ose më shumë."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Fut kodin e saktë PUK. Provat e përsëritura do ta çaktivizojnë përgjithmonë kartën SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kodet PIN nuk përputhen"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Shumë tentativa për motivin"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"E ke shkruar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht kodin PIN.\n\nProvo sërish për <xliff:g id="NUMBER_1">%2$d</xliff:g> sekonda."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"E ke shkruar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht fjalëkalimin.\n\nProvo sërish për <xliff:g id="NUMBER_1">%2$d</xliff:g> sekonda."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për të vizatuar motivin tënd. \n\nProvo sërish për <xliff:g id="NUMBER_1">%2$d</xliff:g> sekonda."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht për ta shkyçur tabletin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> përpjekjeve të tjera të pasuksesshme, tableti do të rivendoset, gjë që do të rivendosë të gjitha të dhënat e tij."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht për ta shkyçur telefonin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> përpjekjeve të tjera të pasuksesshme, telefoni do të rivendoset, gjë që do të fshijë të gjitha të dhënat e tij."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur tabletin. Ky tablet do të rivendoset, gjë që do të fshijë të gjitha të dhënat e tij."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur telefonin. Ky telefon do të rivendoset, gjë që do të fshijë të gjitha të dhënat e tij."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për ta shkyçur telefonin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, përdoruesi do të hiqet dhe të gjitha të dhënat e përdoruesit në të, do të fshihen."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për ta shkyçur telefonin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, përdoruesi do të hiqet dhe të gjitha të dhënat e përdoruesit në të, do të fshihen."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur tabletin. Profili i punës do të hiqet, gjë që do të fshijë të gjitha të dhënat e profilit."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur telefonin. Profili i punës do të hiqet, gjë që do të fshijë të gjitha të dhënat e profilit."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh tabletin duke përdorur një llogari mail-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh telefonin duke përdorur një llogari mail-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Kodi PIN i kartës SIM është i pasaktë. Tani duhet të kontaktosh me operatorin për ta shkyçur pajisjen tënde."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Kodi PIN i kartës SIM është i pasaktë. Të kanë mbetur edhe <xliff:g id="NUMBER_1">%d</xliff:g> tentativa.</item>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index 41869e9..9d5ed28 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притисните Мени да бисте откључали."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежа је закључана"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Нема SIM картице"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"У таблету нема SIM картице."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"У телефону нема SIM картице."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Уметните SIM картицу."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM картица недостаје или не може да се прочита. Уметните SIM картицу."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM картица је неупотребљива."</string>
@@ -84,17 +82,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Унесите PIN који има 4–8 бројева."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK кôд треба да има 8 или више бројева."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Поново унесите тачан PUK кôд. Поновљени покушаји ће трајно онемогућити SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN кодови се не подударају"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Превише покушаја уноса шаблона"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Унели сте погрешан PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Унели сте погрешну лозинку <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Нацртали сте нетачан шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, овај таблет ће се ресетовати, чиме се бришу сви подаци корисника."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, овај телефон ће се ресетовати, чиме се бришу сви подаци корисника."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Овај таблет ће се ресетовати, чиме се бришу сви подаци."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Овај телефон ће се ресетовати, чиме се бришу сви подаци."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -103,10 +94,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо профил за Work, чиме се бришу сви подаци са профила."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо профил за Work, чиме се бришу сви подаци са профила."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, затражићемо да откључате таблет помоћу имејл налога.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, затражићемо да откључате телефон помоћу имејл налога.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Нетачан PIN кôд за SIM. Сада морате да контактирате мобилног оператера да бисте откључали уређај."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Нетачан PIN кôд за SIM. Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушај.</item>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index c35fc1a..595f411 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Lås upp genom att trycka på Meny."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Nätverk låst"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Inget SIM-kort"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Inget SIM-kort i surfplattan."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Inget SIM-kort i mobilen."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Sätt i ett SIM-kort."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM-kort saknas eller kan inte läsas. Sätt i ett SIM-kort."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Oanvändbart SIM-kort."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Ange en pinkod med fyra till åtta siffror."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-koden ska vara minst åtta siffror."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Ange rätt PUK-kod. Om försöken upprepas inaktiveras SIM-kortet permanent."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Pinkoderna stämmer inte överens"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"För många försök med grafiskt lösenord"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Du har angett fel pinkod <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Du har försökt låsa upp surfplattan på ett felaktigt sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök återställs surfplattan och all data raderas."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Du har försökt låsa upp mobilen på ett felaktigt sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök återställs mobilen och all data raderas."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Du har försökt låsa upp surfplattan på ett felaktigt sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Surfplattan återställs och all data raderas."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Du har försökt låsa upp mobilen på ett felaktigt sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Mobilen återställs och all data raderas."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Du har försökt låsa upp surfplattan på ett felaktigt sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök tas användaren bort och all användardata raderas."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Du har försökt låsa upp mobilen på ett felaktigt sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök tas användaren bort och all användardata raderas."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Du har försökt låsa upp surfplattan på ett felaktigt sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Jobbprofilen tas bort och all profildata raderas."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Du har försökt låsa upp mobilen på ett felaktigt sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Jobbprofilen tas bort och all profildata raderas."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök måste du låsa upp surfplattan med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök måste du låsa upp mobilen med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Du angav fel pinkod för SIM-kortet och måste nu kontakta operatören för att låsa upp enheten."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Du angav fel pinkod för SIM-kortet. <xliff:g id="NUMBER_1">%d</xliff:g> försök återstår.</item>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index 30749bd..cb6409e 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Bonyeza Menyu ili kufungua."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mtandao umefungwa"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Hakuna SIM kadi"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Hakuna SIM kadi katika kompyuta kibao."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Hakuna SIM kadi kwenye simu."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Weka SIM kadi."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM kadi haiko au haisomeki. Weka SIM kadi."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM kadi isiyotumika."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Andika PIN ya tarakimu 4 hadi 8."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Nambari ya PUK inafaa kuwa na tarakimu 8 au zaidi."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Weka tena nambari sahihi wa PUK. Ukirudia mara nyingi utafunga SIM kabisa."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Nambari za PIN hazifanani"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Umejaribu kuchora mchoro mara nyingi mno"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Umeandika vibaya PIN mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Umeandika vibaya nenosiri lako mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Umechora vibaya mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Umejaribu kufungua kompyuta kibao mara <xliff:g id="NUMBER_0">%1$d</xliff:g> bila mafanikio. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, kompyuta hii kibao itarejeshwa katika hali iliyotoka nayo kiwandani, hatua itakayofuta data yake yote."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Umejaribu kufungua simu mara <xliff:g id="NUMBER_0">%1$d</xliff:g> bila mafanikio. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, simu hii itarejeshwa katika hali iliyotoka nayo kiwandani, hatua itakayofuta data yake yote."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Umejaribu kufungua simu mara <xliff:g id="NUMBER">%d</xliff:g> bila mafanikio. Kompyuta hii kibao itarejeshwa katika hali iliyotoka nayo kiwandani, hatua itakayofuta data yake yote."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Umejaribu kufungua simu mara <xliff:g id="NUMBER">%d</xliff:g> bila mafanikio. Simu hii itarejeshwa katika hali iliyotoka nayo kiwandani, hatua itakayofuta data yake yote."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Umejaribu kufungua kompyuta kibao mara <xliff:g id="NUMBER_0">%1$d</xliff:g> bila mafanikio. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, mtumiaji huyu ataondolewa, hatua itakayofuta data yake yote."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Umejaribu kufungua simu mara <xliff:g id="NUMBER_0">%1$d</xliff:g> bila mafanikio. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, mtumiaji huyu ataondolewa, hatua itakayofuta data yake yote."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Umejaribu kufungua kompyuta kibao mara <xliff:g id="NUMBER">%d</xliff:g> bila mafanikio. Wasifu wa kazini utaondolewa, hatua itakayofuta data yote ya wasifu."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Umejaribu kufungua simu mara <xliff:g id="NUMBER">%d</xliff:g> bila mafanikio. Wasifu wa kazini utaondolewa, hatua itakayofuta data yote ya wasifu."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, utaombwa kufungua kompyuta yako kibao kwa kutumia akaunti yako ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Nambari ya PIN ya SIM si sahihi, sasa lazima uwasiliane na mtoa huduma za mtandao ndipo ufungue kifaa chako."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Nambari ya PIN ya SIM si sahihi. Una nafasi zingine <xliff:g id="NUMBER_1">%d</xliff:g> za kujaribu.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 756bd8c..63e1a1e 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"திறக்க, மெனுவை அழுத்தவும்."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"நெட்வொர்க் பூட்டப்பட்டது"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"சிம் கார்டு இல்லை"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"டேப்லெட்டில் சிம் கார்டு இல்லை."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"மொபைலில் சிம் கார்டு இல்லை."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"சிம் கார்டைச் செருகவும்."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"சிம் கார்டு செருகப்படவில்லை அல்லது படிக்கக்கூடியதாக இல்லை. சிம் கார்டைச் செருகவும்."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"பயன்படுத்த முடியாத சிம் கார்டு."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 இலிருந்து 8 எண்கள் உள்ள பின்னை உள்ளிடவும்."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK குறியீட்டில் 8 அல்லது அதற்கும் அதிகமான எண்கள் இருக்க வேண்டும்."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"சரியான PUK குறியீட்டை மீண்டும் உள்ளிடவும். தொடர் முயற்சிகள் சிம்மை நிரந்தரமாக முடக்கிவிடும்."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"பின் குறியீடுகள் பொருந்தவில்லை"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"பேட்டர்னை அதிக முறை தவறாக வரைந்துவிட்டீர்கள்"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"உங்கள் பின்னை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக உள்ளிட்டுவிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"உங்கள் கடவுச்சொல்லை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக உள்ளிட்டுவிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"திறப்பதற்கான பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"டேப்லெட்டைத் திறக்க, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக முயன்றால், இந்த டேப்லெட் மீட்டமைக்கப்பட்டு, அதன் எல்லாத் தரவும் நீக்கப்படும்."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"மொபைலைத் திறக்க, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக முயன்றால், இந்த மொபைல் மீட்டமைக்கப்பட்டு, அதன் எல்லாத் தரவும் நீக்கப்படும்."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"டேப்லெட்டைத் திறக்க, <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இந்த டேப்லெட் மீட்டமைக்கப்பட்டு, அதன் எல்லாத் தரவும் நீக்கப்படும்."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"மொபைலைத் திறக்க, <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இந்த மொபைல் மீட்டமைக்கப்பட்டு, அதன் எல்லாத் தரவும் நீக்கப்படும்."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"டேப்லெட்டைத் திறக்க, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக முயன்றால், இந்தப் பயனர் அகற்றப்பட்டு, எல்லாப் பயனர் தரவும் நீக்கப்படும்."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"மொபைலைத் திறக்க, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக முயன்றால், இந்தப் பயனர் அகற்றப்பட்டு, எல்லாப் பயனர் தரவும் நீக்கப்படும்."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"டேப்லெட்டைத் திறக்க, <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். பணிக் கணக்கு அகற்றப்பட்டு, எல்லாச் சுயவிவரத் தரவும் நீக்கப்படும்."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"மொபைலைத் திறக்க, <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். பணிக் கணக்கு அகற்றப்பட்டு, எல்லாச் சுயவிவரத் தரவும் நீக்கப்படும்."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"திறப்பதற்கான பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், மின்னஞ்சல் கணக்கைப் பயன்படுத்தி டேப்லெட்டைத் திறக்கும்படி கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"திறப்பதற்கான பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், மின்னஞ்சல் கணக்கைப் பயன்படுத்தி மொபைலைத் திறக்கும்படி கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"சிம்மின் பின் குறியீடு தவறானது. இனி சாதனத்தைத் திறக்க, உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்புகொள்ள வேண்டும்."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">சிம்மின் பின் குறியீடு தவறானது, இன்னும் நீங்கள் <xliff:g id="NUMBER_1">%d</xliff:g> முறை முயலலாம்.</item>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index f9986d9..a2f45c9 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"అన్లాక్ చేయడానికి మెనుని నొక్కండి."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"నెట్వర్క్ లాక్ చేయబడింది"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM కార్డ్ లేదు"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"టాబ్లెట్లో SIM కార్డ్ లేదు."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ఫోన్లో SIM కార్డ్ లేదు."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM కార్డ్ని చొప్పించండి."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM కార్డ్ లేదు లేదా ఆమోదయోగ్యం కాదు. SIM కార్డ్ని చొప్పించండి."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM కార్డ్ నిరుపయోగకరంగా మారింది."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 నుండి 8 సంఖ్యలు ఉండే పిన్ను టైప్ చేయండి."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK కోడ్ అనేది 8 లేదా అంతకంటే ఎక్కువ సంఖ్యలు ఉండాలి."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"సరైన PUK కోడ్ను మళ్లీ నమోదు చేయండి. ఎక్కువసార్లు ప్రయత్నించడం వలన SIM శాశ్వతంగా నిలిపివేయబడుతుంది."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"పిన్ కోడ్లు సరిపోలలేదు"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"నమూనాని చాలా ఎక్కువసార్లు గీసారు"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"మీరు మీ పిన్ను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"మీరు మీ పాస్వర్డ్ను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"మీరు మీ అన్లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"మీరు టాబ్లెట్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఈ టాబ్లెట్ రీసెట్ చేయబడుతుంది, తద్వారా ఇందులోని మొత్తం డేటా తొలగించబడుతుంది."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"మీరు ఫోన్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఈ ఫోన్ రీసెట్ చేయబడుతుంది, తద్వారా ఇందులోని మొత్తం డేటా తొలగించబడుతుంది."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"మీరు టాబ్లెట్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER">%d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. ఈ టాబ్లెట్ రీసెట్ చేయబడుతుంది, తద్వారా ఇందులోని మొత్తం డేటా తొలగించబడుతుంది."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"మీరు ఫోన్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER">%d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. ఈ ఫోన్ రీసెట్ చేయబడుతుంది, తద్వారా ఇందులోని మొత్తం డేటా తొలగించబడుతుంది."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"మీరు టాబ్లెట్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఈ వినియోగదారు తీసివేయబడతారు, తద్వారా వినియోగదారు డేటా మొత్తం తొలగించబడుతుంది."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"మీరు ఫోన్ని అన్లాక్ చేయడానికి <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఈ వినియోగదారు తీసివేయబడతారు, తద్వారా వినియోగదారు డేటా మొత్తం తొలగించబడుతుంది."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"మీరు టాబ్లెట్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER">%d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. కార్యాలయ ప్రొఫైల్ తీసివేయబడుతుంది, తద్వారా ప్రొఫైల్ డేటా మొత్తం తొలగించబడుతుంది."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"మీరు ఫోన్ని అన్లాక్ చేయడానికి <xliff:g id="NUMBER">%d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. కార్యాలయ ప్రొఫైల్ తీసివేయబడుతుంది, తద్వారా ప్రొఫైల్ డేటా మొత్తం తొలగించబడుతుంది."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"మీరు మీ అన్లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, మీరు ఇమెయిల్ ఖాతాను ఉపయోగించి మీ టాబ్లెట్ను అన్లాక్ చేయాల్సి వస్తుంది.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"మీరు మీ అన్లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, మీరు ఇమెయిల్ ఖాతాను ఉపయోగించి మీ ఫోన్ను అన్లాక్ చేయాల్సి వస్తుంది.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM పిన్ కోడ్ తప్పు, ఇప్పుడు మీ డివైజ్ను అన్లాక్ చేయాలంటే, మీరు తప్పనిసరిగా మీ క్యారియర్ను సంప్రదించాలి."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM పిన్ కోడ్ తప్పు, మీకు మరో <xliff:g id="NUMBER_1">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి.</item>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index 62b04dc..ce40efb 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"กด \"เมนู\" เพื่อปลดล็อก"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"เครือข่ายถูกล็อก"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"ไม่มีซิมการ์ด"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ไม่มีซิมการ์ดในแท็บเล็ต"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ไม่มีซิมการ์ดในโทรศัพท์"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"ใส่ซิมการ์ด"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"ไม่มีซิมการ์ดหรือไม่สามารถอ่านได้ โปรดใส่ซิมการ์ด"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"ซิมการ์ดใช้ไม่ได้"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"พิมพ์ PIN ซึ่งเป็นเลข 4-8 หลัก"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"รหัส PUK ต้องเป็นตัวเลขอย่างน้อย 8 หลัก"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"ใส่รหัส PUK ที่ถูกต้องอีกครั้ง การพยายามซ้ำหลายครั้งจะทำให้ซิมการ์ดถูกปิดใช้งานอย่างถาวร"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"รหัส PIN ไม่ตรง"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"ลองหลายรูปแบบมากเกินไป"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"คุณพิมพ์ PIN ไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%2$d</xliff:g> วินาที"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"คุณพิมพ์รหัสผ่านไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%2$d</xliff:g> วินาที"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> วินาที"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"คุณปลดล็อกแท็บเล็ตไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะรีเซ็ตแท็บเล็ตเครื่องนี้ ซึ่งจะเป็นการลบข้อมูลทั้งหมดในเครื่อง"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"คุณปลดล็อกโทรศัพท์ไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะรีเซ็ตโทรศัพท์เครื่องนี้ ซึ่งจะเป็นการลบข้อมูลทั้งหมดในเครื่อง"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"คุณปลดล็อกแท็บเล็ตไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้ง ระบบจะรีเซ็ตแท็บเล็ตเครื่องนี้ ซึ่งจะเป็นการลบข้อมูลทั้งหมดในเครื่อง"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"คุณปลดล็อกโทรศัพท์ไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้ง ระบบจะรีเซ็ตโทรศัพท์เครื่องนี้ ซึ่งจะเป็นการลบข้อมูลทั้งหมดในเครื่อง"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"คุณปลดล็อกแท็บเล็ตไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะนำผู้ใช้รายนี้ออก ซึ่งจะเป็นการลบข้อมูลทั้งหมดของผู้ใช้"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"คุณปลดล็อกโทรศัพท์ไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะนำผู้ใช้รายนี้ออก ซึ่งจะเป็นการลบข้อมูลทั้งหมดของผู้ใช้"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"คุณปลดล็อกแท็บเล็ตไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้ง ระบบจะนำโปรไฟล์งานออก ซึ่งจะเป็นการลบข้อมูลโปรไฟล์ทั้งหมด"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"คุณปลดล็อกโทรศัพท์ไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้ง ระบบจะนำโปรไฟล์งานออก ซึ่งจะเป็นการลบข้อมูลโปรไฟล์ทั้งหมด"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล\n\n โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%3$d</xliff:g> วินาที"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้บัญชีอีเมล\n\n โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%3$d</xliff:g> วินาที"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"รหัส PIN ของซิมไม่ถูกต้อง ตอนนี้คุณต้องติดต่อผู้ให้บริการเพื่อปลดล็อกอุปกรณ์ของคุณ"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">รหัส PIN ของซิมไม่ถูกต้อง คุณพยายามได้อีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง</item>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index 4841eae..15f9616 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pindutin ang Menu upang i-unlock."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Naka-lock ang network"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Walang SIM card"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Walang SIM card sa tablet."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Walang SIM card sa telepono."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Maglagay ng SIM card."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Wala o hindi nababasa ang SIM card. Maglagay ng SIM card."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Hindi na magagamit na SIM card."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Mag-type ng PIN na 4 hanggang 8 numero."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Dapat ay 8 numero o higit pa ang PUK code."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Muling ilagay ang tamang PUK code. Permanenteng madi-disable ang SIM dahil sa paulit-ulit na pagsubok."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Hindi nagtutugma ang mga PIN code"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Masyadong maraming pagsubok sa pattern"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Na-type mo nang mali ang iyong PIN nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Na-type mo nang hindi tama ang iyong password nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses mo nang sinubukang i-unlock ang tablet gamit ang maling password. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, ire-reset ang tablet na ito, na magiging dahilan upang ma-delete ang lahat ng data nito."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses mo nang sinubukang i-unlock ang telepono gamit ang maling password. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, ire-reset ang teleponong ito, na magiging dahilan upang ma-delete ang lahat ng data nito."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"<xliff:g id="NUMBER">%d</xliff:g> (na) beses mo nang sinubukang i-unlock ang tablet gamit ang maling password. Ire-reset ang tablet na ito, na magiging dahilan upang ma-delete ang lahat ng data nito."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"<xliff:g id="NUMBER">%d</xliff:g> (na) beses mo nang sinubukang i-unlock ang telepono gamit ang maling password. Ire-reset ang teleponong ito, na magiging dahilan upang ma-delete ang lahat ng data nito."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses mo nang sinubukang i-unlock ang tablet gamit ang maling password. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, aalisin ang user na ito, na magiging dahilan upang ma-delete ang lahat ng data ng user."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses mo nang sinubukang i-unlock ang telepono gamit ang maling password. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, aalisin ang user na ito, na magiging dahilan upang ma-delete ang lahat ng data ng user."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"<xliff:g id="NUMBER">%d</xliff:g> (na) beses mo nang sinubukang i-unlock ang tablet gamit ang maling password. Aalisin ang profile sa trabaho, na magiging dahilan upang ma-delete ang lahat ng data sa profile."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"<xliff:g id="NUMBER">%d</xliff:g> (na) beses mo nang sinubukang i-unlock ang telepono gamit ang maling password. Aalisin ang profile sa trabaho, na magiging dahilan upang ma-delete ang lahat ng data sa profile."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Mali ang PIN code ng SIM, dapat ka nang makipag-ugnayan sa iyong carrier upang i-unlock ang iyong device."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Mali ang PIN code ng SIM, mayroon kang <xliff:g id="NUMBER_1">%d</xliff:g> natitirang pagsubok.</item>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index 3985163..2ddf26e 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Kilidi açmak için Menü\'ye basın."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Ağ kilitli"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM kart yok"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Tablette SIM kart yok."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefonda SIM kart yok."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"SIM kart takın."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM kart yok veya okunamıyor. Bir SIM kart takın."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Kullanılamayan SIM kartı"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 ila 8 haneli bir PIN yazın."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kodu 8 veya daha çok basamaklı bir sayı olmalıdır."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Doğru PUK kodunu tekrar girin. Çok sayıda deneme yapılırsa SIM kart kalıcı olarak devre dışı bırakılır."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodları eşleşmiyor"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Çok fazla sayıda desen denemesi yapıldı"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN kodunuzu <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış girdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Şifrenizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış yazdınız. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Tabletin kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı bir şekilde açmayı denediniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız bu tablet sıfırlanacak ve tüm verileri silinecektir."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Telefonun kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı bir şekilde açmayı denediniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız bu telefon sıfırlanacak ve tüm verileri silinecektir."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Tabletin kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmayı denediniz. Bu tablet sıfırlanacak ve tüm verileri silinecektir."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Telefonun kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmayı denediniz. Bu telefon sıfırlanacak ve tüm verileri silinecektir."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Tabletin kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı bir şekilde açmayı denediniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız bu kullanıcı kaldırılacak ve tüm kullanıcı verileri silinecektir."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Telefonun kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı bir şekilde açmayı denediniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız bu kullanıcı kaldırılacak ve tüm kullanıcı verileri silinecektir."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Tabletin kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmayı denediniz. İş profili kaldırılacak ve tüm profil verileri silinecektir."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Telefonun kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmayı denediniz. İş profili kaldırılacak ve tüm profil verileri silinecektir."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> defa yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız denemeden sonra, tabletinizin kilidini bir e-posta hesabı kullanarak açmanız istenir.\n<xliff:g id="NUMBER_2">%3$d</xliff:g>\n saniye içinde tekrar deneyin."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız denemeden sonra telefonunuzun kilidini bir e-posta hesabı kullanarak açmanız istenir.\n<xliff:g id="NUMBER_2">%3$d</xliff:g>\n saniye içinde tekrar deneyin."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Yanlış SIM PIN kodu. Cihazınızın kilidini açmak için artık operatörünüzle bağlantı kurmanız gerekiyor."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Yanlış SIM PIN kodu, <xliff:g id="NUMBER_1">%d</xliff:g> deneme hakkınız kaldı.</item>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index 097d735..fd15745 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Натисніть меню, щоб розблокувати."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Мережу заблоковано"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Немає SIM-карти"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"У пристрої немає SIM-карти."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"У телефоні немає SIM-карти."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Вставте SIM-карту."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM-карта відсутня або недоступна для читання. Вставте SIM-карту."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Непридатна SIM-карта."</string>
@@ -85,17 +83,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Введіть PIN-код із 4–8 цифр."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-код має складатися зі щонайменше 8 цифр."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Повторно введіть правильний PUK-код. Численні спроби назавжди вимкнуть SIM-карту."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-коди не збігаються"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Забагато спроб намалювати ключ"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN-код неправильно введено стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%2$d</xliff:g> с."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Пароль неправильно введено стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%2$d</xliff:g> с."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%2$d</xliff:g> с."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Кількість невдалих спроб розблокувати планшет: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі буде скинуто налаштування планшета й видалено всі його дані."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі буде скинуто налаштування телефона й видалено всі його дані."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Кількість невдалих спроб розблокувати планшет: <xliff:g id="NUMBER">%d</xliff:g>. Буде скинуто налаштування цього планшета й видалено всі його дані."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER">%d</xliff:g>. Буде скинуто налаштування цього телефона й видалено всі його дані."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Кількість невдалих спроб розблокувати планшет: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі буде видалено цього користувача й усі його дані."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі буде видалено цього користувача й усі його дані."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -104,10 +95,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Кількість невдалих спроб розблокувати планшет: <xliff:g id="NUMBER">%d</xliff:g>. Буде видалено робочий профіль і всі його дані."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER">%d</xliff:g>. Буде видалено робочий профіль і всі його дані."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі з’явиться запит розблокувати планшет за допомогою облікового запису електронної пошти.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі з’явиться запит розблокувати телефон за допомогою облікового запису електронної пошти.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Неправильний PIN-код SIM-карти. Зв’яжіться зі своїм оператором, щоб розблокувати пристрій."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Неправильний PIN-код SIM-карти. У вас залишилася <xliff:g id="NUMBER_1">%d</xliff:g> спроба.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 0a4340f..04d29c6 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"غیر مقفل کرنے کیلئے مینو دبائیں۔"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"نیٹ ورک مقفل ہو گیا"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"کوئی SIM کارڈ نہیں ہے"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ٹیبلیٹ میں کوئی SIM کارڈ نہیں ہے۔"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"فون میں کوئی SIM کارڈ نہيں ہے۔"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"ایک SIM کارڈ داخل کریں۔"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM کارڈ غائب ہے یا پڑھنے کے قابل نہیں ہے۔ ایک SIM کارڈ داخل کریں۔"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"ناقابل استعمال SIM کارڈ۔"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"ایسا PIN ٹائپ کریں جو 4 تا 8 اعداد پر مشتمل ہو۔"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK کوڈ 8 یا زائد اعداد پر مشتمل ہونا چاہیے۔"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"صحیح PUK کوڈ دوبارہ درج کریں۔ بار بار کی کوششیں SIM کو مستقل طور پر غیر فعال کر دیں گی۔"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN کوڈز مماثل نہیں ہیں"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"پیٹرن کی بہت ساری کوششیں"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"آپ نے اپنا PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"آپ نے اپنا پاسورڈ <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"آپ نے ٹیبلیٹ کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، اس ٹیبلیٹ کو دوبارہ ترتیب دے دیا جائے گا، جس سے اس کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"آپ نے فون کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، اس فون کو دوبارہ ترتیب دے دیا جائے گا، جس سے اس کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"آپ نے ٹیبلیٹ کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ اس ٹیبلیٹ کو دوبارہ ترتیب دے دیا جائے گا، جس سے اس کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"آپ نے فون کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ اس فون کو دوبارہ ترتیب دے دیا جائے گا، جس سے اس کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"آپ نے ٹیبلیٹ کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، اس صارف کو ہٹا دیا جائے گا، جس سے صارف کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"آپ نے فون کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، اس صارف کو ہٹا دیا جائے گا، جس سے صارف کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"آپ نے ٹیبلیٹ کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ دفتری پروفائل ہٹا دیا جائے گا، جس سے پروفائل کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"آپ نے فون کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ دفتری پروفائل ہٹا دیا جائے گا، جس سے پروفائل کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کرکے اپنا ٹیبلیٹ غیر مقفل کرنے کو کہا جائے گا۔\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کرکے اپنا فون غیر مقفل کرنے کو کہا جائے گا۔\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"غلط SIM PIN کوڈ، اب آپ کو اپنا آلہ غیر مقفل کرنے کیلئے اپنے کیریئر سے رابطہ کرنا ہوگا۔"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">غلط SIM PIN کوڈ، آپ کے پاس <xliff:g id="NUMBER_1">%d</xliff:g> کوششیں بچی ہیں۔</item>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index 1780ba01..ce461fe 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Qulfdan chiqarish uchun Menyu tugmasini bosing."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Tarmoq qulflangan"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"SIM karta solinmagan"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Planshetingizda SIM karta yo‘q."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefoningizda SIM karta yo‘q."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Telefonga SIM karta soling."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM karta solinmagan yoki u yaroqsiz. SIM karta soling."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Foydalanib bo‘lmaydigan SIM karta."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4-8 ta raqamdan iborat PIN kodni kiriting."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kod kamida 8 ta raqamdan iborat bo‘lishi shart."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"To‘g‘ri PUK kodni qayta kiriting. Qayta-qayta urinishlar SIM kartani butunlay o‘chirib qo‘yadi."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kod mos kelmadi"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Grafik kalit juda ko‘p marta chizildi"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN kod <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato kiritildi. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> soniyadan keyin qaytadan urining."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Parol <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato kiritildi. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> soniyadan keyin qaytadan urining."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Grafik kalit <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato kiritildi. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> soniyadan keyin qayta urining."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Siz planshetni qulfdan chiqarish uchun <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri urinish qildingiz. Agar yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinish qilsangiz, ushbu planshetda zavod sozlamalari qayta tiklanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Siz telefonni qulfdan chiqarish uchun <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri urinish qildingiz. Agar yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinish qilsangiz, ushbu telefonda zavod sozlamalari qayta tiklanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Siz planshetni qulfdan chiqarish uchun <xliff:g id="NUMBER">%d</xliff:g> marta noto‘g‘ri urinish qildingiz. Endi, ushbu planshetda zavod sozlamalari qayta tiklanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Siz telefonni qulfdan chiqarish uchun <xliff:g id="NUMBER">%d</xliff:g> marta noto‘g‘ri urinish qildingiz. Endi, ushbu telefonda zavod sozlamalari qayta tiklanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Siz planshetni qulfdan chiqarish uchun <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri urinish qildingiz. Agar yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinish qilsangiz, ushbu foydalanuvchi o‘chirib tashlanadi va undagi barcha foydalanuvchi ma’lumotlari ham o‘chib ketadi."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Siz telefonni qulfdan chiqarish uchun <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri urinish qildingiz. Agar yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinish qilsangiz, ushbu foydalanuvchi o‘chirib tashlanadi va undagi barcha foydalanuvchi ma’lumotlari ham o‘chib ketadi."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Siz planshetni qulfdan chiqarish uchun <xliff:g id="NUMBER">%d</xliff:g> marta noto‘g‘ri urinish qildingiz. Endi, ishchi profil o‘chirib tashlanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Siz telefonni qulfdan chiqarish uchun <xliff:g id="NUMBER">%d</xliff:g> marta noto‘g‘ri urinish qildingiz. Endi, ishchi profil o‘chirib tashlanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Grafik kalit <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato chizildi. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan keyin, sizdan e-pochtangizdan foydalanib, planshet qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan keyin yana urinib ko‘ring."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Grafik kalit <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato chizildi. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan keyin, sizdan e-pochtangizdan foydalanib, telefon qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan keyin qayta urinib ko‘ring."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM kartaning PIN kodi xato. Qurilma qulfini ochish uchun operatoringizga murojaat qiling."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM kartaning PIN kodi noto‘g‘ri. Sizda yana <xliff:g id="NUMBER_1">%d</xliff:g> ta urinish qoldi.</item>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index 57b359a..3ac2cd2 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Nhấn vào Menu để mở khóa."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mạng đã bị khóa"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Không có thẻ SIM"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Không có thẻ SIM nào trong máy tính bảng."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Không có thẻ SIM nào trong điện thoại."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Lắp thẻ SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Thẻ SIM bị thiếu hoặc không thể đọc được. Hãy lắp thẻ SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Thẻ SIM không sử dụng được."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Nhập mã PIN có từ 4 đến 8 số."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Mã PUK phải có từ 8 số trở lên."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Hãy nhập lại mã PUK chính xác. Nhiều lần lặp lại sẽ vô hiệu hóa vĩnh viễn thẻ SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Mã PIN không khớp"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Quá nhiều lần nhập hình mở khóa"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Bạn đã nhập sai mã PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%2$d</xliff:g> giây."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Bạn đã nhập sai mật khẩu <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%2$d</xliff:g> giây."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Bạn đã vẽ không chính xác hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%2$d</xliff:g> giây."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Bạn đã mở khóa máy tính bảng sai <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, máy tính bảng này sẽ được đặt lại, tức là tất cả dữ liệu của máy tính bảng sẽ bị xóa."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Bạn đã mở khóa điện thoại sai <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, điện thoại này sẽ được đặt lại, tức là tất cả dữ liệu của điện thoại sẽ bị xóa."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Bạn đã mở khóa máy tính bảng sai <xliff:g id="NUMBER">%d</xliff:g> lần. Máy tính bảng này sẽ được đặt lại, tức là tất cả dữ liệu của máy tính bảng sẽ bị xóa."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Bạn đã mở khóa điện thoại sai <xliff:g id="NUMBER">%d</xliff:g> lần. Điện thoại này sẽ được đặt lại, tức là tất cả dữ liệu của điện thoại sẽ bị xóa."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Bạn đã mở khóa máy tính bảng sai <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, người dùng này sẽ bị xóa, tức là tất cả dữ liệu người dùng sẽ bị xóa."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Bạn đã mở khóa điện thoại sai <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, người dùng này sẽ bị xóa, tức là tất cả dữ liệu người dùng sẽ bị xóa."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Bạn đã mở khóa máy tính bảng sai <xliff:g id="NUMBER">%d</xliff:g> lần. Hồ sơ công việc sẽ bị xóa, tức là tất cả dữ liệu hồ sơ sẽ bị xóa."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Bạn đã mở khóa điện thoại sai <xliff:g id="NUMBER">%d</xliff:g> lần. Hồ sơ công việc sẽ bị xóa, tức là tất cả dữ liệu hồ sơ sẽ bị xóa."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Bạn đã vẽ không chính xác hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Bạn đã vẽ không chính xác hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Mã PIN của SIM không chính xác, bây giờ bạn phải liên hệ với nhà cung cấp dịch vụ để mở khóa thiết bị của mình."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">Mã PIN của SIM không chính xác, bạn còn <xliff:g id="NUMBER_1">%d</xliff:g> lần thử.</item>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index 54f1296..0d97946 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按“菜单”即可解锁。"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"网络已锁定"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"没有 SIM 卡"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"平板电脑中没有 SIM 卡。"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"手机中没有 SIM 卡。"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"请插入 SIM 卡。"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"SIM 卡缺失或无法读取,请插入 SIM 卡。"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM 卡无法使用。"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"请输入 4 到 8 位数的 PIN 码。"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK 码应至少包含 8 位数字。"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"请重新输入正确的 PUK 码。如果屡次输入错误,SIM 卡将被永久停用。"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN 码不匹配"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"图案尝试次数过多"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"您已经 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次输错 PIN 码。\n\n请在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒后重试。"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"您已经 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次输错密码。\n\n请在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒后重试。"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"您已经 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次画错解锁图案。\n\n请在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒后重试。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"您尝试解锁平板电脑后失败的次数已达 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,平板电脑将会被重置,而这将删除其中的所有数据。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"您尝试解锁手机后失败的次数已达 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,手机将会被重置,而这将删除其中的所有数据。"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"您尝试解锁平板电脑后失败的次数已达 <xliff:g id="NUMBER">%d</xliff:g> 次。这部平板电脑将会被重置,而这将删除其中的所有数据。"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"您尝试解锁手机后失败的次数已达 <xliff:g id="NUMBER">%d</xliff:g> 次。这部手机将会被重置,而这将删除其中的所有数据。"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"您尝试解锁平板电脑后失败的次数已达 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统将移除此用户,而这将删除所有的用户数据。"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"您尝试解锁手机后失败的次数已达 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统将移除此用户,而这将删除所有的用户数据。"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"您尝试解锁平板电脑后失败的次数已达 <xliff:g id="NUMBER">%d</xliff:g> 次。系统将移除此工作资料,而这将删除所有的工作资料数据。"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"您尝试解锁手机后失败的次数已达 <xliff:g id="NUMBER">%d</xliff:g> 次。系统将移除此工作资料,而这将删除所有的工作资料数据。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒后重试。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒后重试。"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM 卡 PIN 码不正确,您现在必须联系运营商为您解锁设备。"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM 卡 PIN 码不正确,您还有 <xliff:g id="NUMBER_1">%d</xliff:g> 次尝试机会。</item>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index c49380e..1f55b32 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按下 [選單] 即可解鎖。"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"網絡已鎖定"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"沒有 SIM 卡"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"平板電腦中沒有 SIM 卡。"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"手機中沒有 SIM 卡。"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"請插入 SIM 卡。"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"找不到或無法讀取 SIM 卡。請插入 SIM 卡。"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM 卡無法使用。"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"請輸入 4 至 8 位數的 PIN 碼。"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK 碼應由 8 個或以上數字組成。"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"請重新輸入正確的 PUK 碼。如果錯誤輸入的次數過多,SIM 卡將永久停用。"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN 碼不符"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"上鎖圖案畫錯次數過多"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將重設此平板電腦,而平板電腦的所有資料亦會一併刪除。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將重設此手機,而手機的所有資料亦會一併刪除。"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將重設此平板電腦,而平板電腦的所有資料亦會一併刪除。"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將重設此手機,而手機的所有資料亦會一併刪除。"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM 卡 PIN 碼不正確,您現在必須聯絡流動網絡供應商為您的裝置解鎖。"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM 卡的 PIN 碼不正確,您還有 <xliff:g id="NUMBER_1">%d</xliff:g> 次輸入機會。</item>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index 4d4d360..97653c9 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按選單鍵解鎖。"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"網路已鎖定"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"沒有 SIM 卡"</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"平板電腦中沒有 SIM 卡。"</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"手機中沒有 SIM 卡。"</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"請插入 SIM 卡。"</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"找不到或無法讀取 SIM 卡。請插入 SIM 卡。"</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"SIM 卡無法使用。"</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"請輸入 4 到 8 碼的 PIN 碼。"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK 碼至少必須為 8 碼。"</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"請重新輸入正確的 PUK 碼。如果錯誤次數過多,SIM 卡將會遭到永久停用。"</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN 碼不符"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"解鎖圖案畫錯次數過多"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"你已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"你已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"你已畫出錯誤的解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統會重設這台平板電腦,其中的所有資料也會一併遭到刪除。"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統會重設這支手機,其中的所有資料也會一併遭到刪除。"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統會重設這台平板電腦,其中的所有資料也會一併遭到刪除。"</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統會重設這支手機,其中的所有資料也會一併遭到刪除。"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,這位使用者將遭到移除,所有相關的使用者資料也會一併遭到刪除。"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,這位使用者將遭到移除,所有相關的使用者資料也會一併遭到刪除。"</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。你的工作資料夾將遭到移除,所有設定檔資料也會一併遭到刪除。"</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。你的工作資料夾將遭到移除,所有設定檔資料也會一併遭到刪除。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"你的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統就會要求你透過電子郵件帳戶解鎖平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"你的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統就會要求你透過電子郵件帳戶解鎖手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM 卡的 PIN 碼輸入錯誤,你現在必須請電信業者為裝置解鎖。"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM 卡的 PIN 碼輸入錯誤,你還可以再試 <xliff:g id="NUMBER_1">%d</xliff:g> 次。</item>
diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml
index 604bb9d..fe81d02 100644
--- a/packages/SystemUI/res-keyguard/values-zu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml
@@ -42,8 +42,6 @@
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Chofoza Menyu ukuvula."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Inethiwekhi ivaliwe"</string>
<string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"Alikho ikhadi le-SIM."</string>
- <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Alikho ikhadi le-SIM efonini."</string>
- <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Alikho ikhadi le-SIM efonini."</string>
<string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"Faka ikhadi le-SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="2712623293749378570">"Ikhadi le-SIM alitholakali noma alifundeki. Sicela ufake ikhadi le-SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="5842745213110966962">"Ikhadi le-SIM elingasetshenzisiwe."</string>
@@ -83,17 +81,10 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Thayipha i-PIN enezinombolo ezingu-4 kuya kwezingu-8."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Ikhodi ye-PUK kufanele ibe yizinombolo ezingu-8 noma eziningi."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Faka kabusha ikhodi ye-PUK elungile. Imizamo ephindiwe izokhubaza unaphakade i-SIM."</string>
- <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Iphinikhodi ayifani"</string>
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"Kunemizamo eminingi kakhulu yephathini!"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Ubhale iphinikhodi ykho ngendlela engafanele izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nZama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%1$d</xliff:g> izikhathi. \n\nZama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Udwebe iphathini yakho yokuvula ngendlela engafanele-<xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Uzame ngokungalungile ukuvula ithebulethi izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphezulu kwengu-<xliff:g id="NUMBER_1">%2$d</xliff:g> engaphumelelanga, le thebulethi izosethwa kabusha, okuzosusa yonke idatha yayo."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Uzame ngokungalungile ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphezulu kwengu-<xliff:g id="NUMBER_1">%2$d</xliff:g> engaphumelelanga, le foni izosethwa kabusha, okuzosusa yonke idatha yayo."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Uzame ngokungalungile ukuvula ithebulethi izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Le thebulethi izosethwa kabusha, okuzosusa yonke idatha yayo."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Uzame ngokungalungile ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Le foni izosethwa kabusha, okuzosusa yonke idatha yayo."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Uzame ngokungalungile ukuvula ithebulethi izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphezulu kwengu-<xliff:g id="NUMBER_1">%2$d</xliff:g> engaphumelelanga, lo msebenzisi uzosuswa, okuzosusa yonke idatha yomsebenzisi."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Uzame ngokungalungile ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphezulu kwengu-<xliff:g id="NUMBER_1">%2$d</xliff:g> engaphumelelanga, lo msebenzisi uzosuswa, okuzosusa yonke idatha yomsebenzisi."</string>
<!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
<skip />
<!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
@@ -102,10 +93,6 @@
<skip />
<!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
<skip />
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Uzame ngokungalungile ukuvula ithebulethi izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Iphrofayela yomsebenzi izosuswa, okuzosusa yonke idatha yephrofayela."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Uzame ngokungalungile ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Iphrofayela yomsebenzi izosuswa, okuzosusa yonke idatha yephrofayela."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Udwebe ngokungalungile iphethini yakho yokuvula ngezikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphumelelanga kaningi engu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, uzocelwa ukuthi uvule ithebulethi yakho usebenzisa i-akhawunti ye-imeyili.\n\nZama futhi kumasekhondi angu-<xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%1$d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%3$d</xliff:g> imizuzwana."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Ikhodi yephinikhodi ye-SIM engalungile manje kumele uxhumane nenkampini yenethiwekhi yakho ukuvula idivayisi yakho."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="one">Ikhodi engalungile yephinikhodi ye-SIM, unemizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g> esele.</item>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 485240a..f7e9fed 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -91,10 +91,6 @@
<string name="keyguard_network_locked_message">Network locked</string>
<!-- Shown when there is no SIM card. -->
<string name="keyguard_missing_sim_message_short">No SIM card</string>
- <!-- Shown when there is no SIM card. -->
- <string name="keyguard_missing_sim_message" product="tablet">No SIM card in tablet.</string>
- <!-- Shown when there is no SIM card. -->
- <string name="keyguard_missing_sim_message" product="default">No SIM card in phone.</string>
<!-- Shown to ask the user to insert a SIM card. -->
<string name="keyguard_missing_sim_instructions">Insert a SIM card.</string>
<!-- Shown to ask the user to insert a SIM card when sim is missing or not readable. -->
@@ -189,8 +185,6 @@
<string name="kg_invalid_sim_puk_hint">PUK code should be 8 numbers or more.</string>
<!-- Message shown when the user enters an invalid PUK code -->
<string name="kg_invalid_puk">Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM.</string>
- <!-- String shown in PUK screen when PIN codes don't match -->
- <string name="kg_invalid_confirm_pin_hint" product="default">PIN codes does not match</string>
<!-- Message shown when the user exceeds the maximum number of pattern attempts -->
<string name="kg_login_too_many_attempts">Too many pattern attempts</string>
<!-- Message shown in dialog when max number of attempts are reached for PIN screen of keyguard -->
@@ -208,92 +202,6 @@
\n\nTry again in <xliff:g id="number">%2$d</xliff:g> seconds.
</string>
- <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet">
- You have incorrectly attempted to unlock the tablet <xliff:g id="number">%1$d</xliff:g> times.
- After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
- this tablet will be reset, which will delete all its data.
- </string>
- <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_almost_at_wipe" product="default">
- You have incorrectly attempted to unlock the phone <xliff:g id="number">%1$d</xliff:g> times.
- After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
- this phone will be reset, which will delete all its data.
- </string>
- <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_now_wiping" product="tablet">
- You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
- This tablet will be reset, which will delete all its data.
- </string>
- <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_now_wiping" product="default">
- You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
- This phone will be reset, which will delete all its data.
- </string>
-
- <!-- Message shown when user is almost at the limit of password attempts where the user will be removed. [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet">
- You have incorrectly attempted to unlock the tablet <xliff:g id="number">%1$d</xliff:g> times.
- After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
- this user will be removed, which will delete all user data.
- </string>
- <!-- Message shown when user is almost at the limit of password attempts where the user will be removed. [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_almost_at_erase_user" product="default">
- You have incorrectly attempted to unlock the phone <xliff:g id="number">%1$d</xliff:g> times.
- After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
- this user will be removed, which will delete all user data.
- </string>
- <!-- Message shown in dialog when user has exceeded the maximum attempts and the user will be removed. [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_now_erasing_user" product="tablet">
- You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
- This user will be removed, which will delete all user data.
- </string>
- <!-- Message shown in dialog when user has exceeded the maximum attempts and the user will be removed. [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_now_erasing_user" product="default">
- You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
- This user will be removed, which will delete all user data.
- </string>
-
- <!-- Message shown when user is almost at the limit of password attempts where the profile will be removed. [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet">
- You have incorrectly attempted to unlock the tablet <xliff:g id="number">%1$d</xliff:g> times.
- After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
- the work profile will be removed, which will delete all profile data.
- </string>
- <!-- Message shown when user is almost at the limit of password attempts where the profile will be removed. [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_almost_at_erase_profile" product="default">
- You have incorrectly attempted to unlock the phone <xliff:g id="number">%1$d</xliff:g> times.
- After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
- the work profile will be removed, which will delete all profile data.
- </string>
- <!-- Message shown in dialog when user has exceeded the maximum attempts and the profile will be removed. [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet">
- You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
- The work profile will be removed, which will delete all profile data.
- </string>
- <!-- Message shown in dialog when user has exceeded the maximum attempts and the profile will be removed. [CHAR LIMIT=none] -->
- <string name="kg_failed_attempts_now_erasing_profile" product="default">
- You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
- The work profile will be removed, which will delete all profile data.
- </string>
-
- <!-- Message shown in dialog when user is almost at the limit where they will be
- locked out and may have to enter an alternate username/password to unlock the phone -->
- <string name="kg_failed_attempts_almost_at_login" product="tablet">
- You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
- After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
- you will be asked to unlock your tablet using an email account.\n\n
- Try again in <xliff:g id="number">%3$d</xliff:g> seconds.
- </string>
- <!-- Message shown in dialog when user is almost at the limit where they will be
- locked out and may have to enter an alternate username/password to unlock the phone -->
- <string name="kg_failed_attempts_almost_at_login" product="default">
- You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
- After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
- you will be asked to unlock your phone using an email account.\n\n
- Try again in <xliff:g id="number">%3$d</xliff:g> seconds.
- </string>
-
<!-- Instructions telling the user that they entered the wrong SIM PIN for the last time.
Displayed in a dialog box. -->
<string name="kg_password_wrong_pin_code_pukked">Incorrect SIM PIN code you must now contact your carrier to unlock your device.</string>
diff --git a/packages/SystemUI/res-product/values-af/strings.xml b/packages/SystemUI/res-product/values-af/strings.xml
new file mode 100644
index 0000000..61ccec8
--- /dev/null
+++ b/packages/SystemUI/res-product/values-af/strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Geen SIM-kaart in tablet nie."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Geen SIM-kaart in foon nie."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-kodes stem nie ooreen nie"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Jy het die tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd probeer ontsluit. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal hierdie tablet teruggestel word, wat al sy data sal uitvee."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Jy het die foon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd probeer ontsluit. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal hierdie foon teruggestel word, wat al sy data sal uitvee."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Jy het die tablet <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Hierdie tablet sal teruggestel word, wat al sy data sal uitvee."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Jy het die foon <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Hierdie foon sal teruggestel word, wat al sy data sal uitvee."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Jy het die tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd probeer ontsluit. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal hierdie gebruiker verwyder word, wat alle gebruikerdata sal uitvee."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Jy het die foon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd probeer ontsluit. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal hierdie gebruiker verwyder word, wat alle gebruikerdata sal uitvee."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Die Android TV-toestel gaan binnekort afskakel; druk \'n knoppie om dit aan te hou."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Die toestel gaan binnekort afskakel; druk om dit aan te hou."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Jy het die tablet <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Die werkprofiel sal verwyder word, wat alle profieldata sal uitvee."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Jy het die foon <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Die werkprofiel sal verwyder word, wat alle profieldata sal uitvee."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou e-posrekening te gebruik om jou tablet te ontsluit.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou e-posrekening te gebruik om jou foon te ontsluit.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-am/strings.xml b/packages/SystemUI/res-product/values-am/strings.xml
new file mode 100644
index 0000000..4628b2b
--- /dev/null
+++ b/packages/SystemUI/res-product/values-am/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"በጡባዊ ውስጥ ምንም ሲም ካርድ የለም።"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"በስልክ ውስጥ ምንም ሲም ካርድ የለም።"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ፒን ኮዶቹ አይገጣጠሙም"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ጡባዊውን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለማስከፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ይህ ጡባዊ ዳግም ይጀመራል፣ ይህም ሁሉንም ውሂብ ይሰርዛል።"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ስልኩን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለማስከፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ይህ ስልክ ዳግም ይጀመራል፣ ይህም ሁሉንም ውሂብ ይሰርዛል።"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ጡባዊውን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ ሁኔታ ለማስከፈት ሞክረዋል። ስልኩ ዳግም ይጀመራል፣ ይህም ሁሉንም ውሂቡን ይሰርዛል።"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ስልኩን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ ሁኔታ ለማስከፈት ሞክረዋል። ስልኩ ዳግም ይጀመራል፣ ይህም ሁሉንም ውሂቡን ይሰርዛል።"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ጡባዊውን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለማስከፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ይህ ተጠቃሚ ይወገዳል፣ ይህም ሁሉንም የተጠቃሚ ውሂብ ይሰርዛል።"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ስልኩን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለማስከፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ይህ ተጠቃሚ ይወገዳል፣ ይህም ሁሉንም የተጠቃሚ ውሂብ ይሰርዛል።"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"የAndroid TV መሣሪያው በቅርቡ ይጠፋል፣ እንደበራ ለማቆየት ይጫኑ።"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"መሣሪያው በቅርቡ ይጠፋል፤ እንደበራ ለማቆየት ይጫኑ።"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ጡባዊውን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለመክፈት ሞክረዋል። የስራ መገለጫው ይወገዳል፣ ይህም ሁሉንም የመገለጫ ውሂብ ይሰርዛል።"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ስልኩን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለመክፈት ሞክረዋል። የስራ መገለጫው ይወገዳል፣ ይህም ሁሉንም የመገለጫ ውሂብ ይሰርዛል።"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊዎን እንዲከፍቱ ይጠየቃሉ።\n\n ከ<xliff:g id="NUMBER_2">%3$d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።\n\nእባክዎ ከ<xliff:g id="NUMBER_2">%3$d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ar/strings.xml b/packages/SystemUI/res-product/values-ar/strings.xml
new file mode 100644
index 0000000..09aa42e
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ar/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ليست هناك شريحة SIM في الجهاز اللوحي."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ليست هناك شريحة SIM في الهاتف."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"لا يتطابق رمز رقم التعريف الشخصي"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"أخطأت في محاولة إلغاء قفل الجهاز اللوحي <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستتم إعادة تعيين هذا الجهاز، ومن ثم يتم حذف جميع بياناته."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"أخطأت في محاولة إلغاء قفل الهاتف <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستتم إعادة تعيين هذا الهاتف، ومن ثم يتم حذف جميع بياناته."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"أخطأت في محاولة إلغاء قفل الجهاز اللوحي <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم إعادة تعيين هذا الجهاز، ومن ثم يتم حذف جميع بياناته."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"أخطأت في محاولة إلغاء قفل الهاتف <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم إعادة تعيين هذا الهاتف، ومن ثم يتم حذف جميع بياناته."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"أخطأت في محاولة إلغاء قفل الجهاز اللوحي <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستتم إزالة هذا المستخدم، ومن ثم يتم حذف جميع بيانات المستخدم."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"أخطأت في محاولة إلغاء قفل الهاتف <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستتم إزالة هذا المستخدم، ومن ثم يتم حذف جميع بيانات المستخدم."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"سيتم إيقاف جهاز Android TV قريبًا، اضغط على أحد الأزرار لمواصلة تشغيله."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"سيتم إيقاف الجهاز قريبًا، اضغط لمواصلة تشغيله."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"أخطأت في محاولة إلغاء قفل الجهاز اللوحي <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بياناته."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"أخطأت في محاولة إلغاء قفل الهاتف <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بياناته."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"لقد رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"لقد رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-as/strings.xml b/packages/SystemUI/res-product/values-as/strings.xml
new file mode 100644
index 0000000..1f1ca09
--- /dev/null
+++ b/packages/SystemUI/res-product/values-as/strings.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"টেবলেটত ছিম কার্ড নাই।"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ফ\'নত ছিম কার্ড নাই।"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"পিন ক\'ড মিলা নাই"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে টেবলেটটো ৰিছেট কৰা হ\'ব, যি কার্যই টেবলেটটোত থকা সকলো ডেটা মচিব।"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে ফ\'নটো ৰিছেট কৰা হ\'ব, যি কার্যই ফ\'নটোত থকা সকলো ডেটা মচিব।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। এই টেবলেটটো ৰিছেট কৰা হ\'ব, যি কার্যই ইয়াৰ সকলো ডেটা মচিব।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। এই ফ\'নটো ৰিছেট কৰা হ\'ব, যিয়ে ইয়াৰ সকলো ডেটা মচিব।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে এই ব্যৱহাৰকাৰীক আঁতৰোৱা হ\'ব, যিয়ে ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিব।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে এই ব্যৱহাৰকাৰীক আঁতৰোৱা হ\'ব, যিয়ে ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিব।"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for notification_bubble_title (8330481035191903164) -->
+ <skip/>
+ <!-- no translation found for notification_channel_summary_bubble (7235935211580860537) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ডিভাইচটো অতি সোনকালে অফ হ\'ব, এইটো অন ৰাখিবলৈ যিকোনো এটা বুটাম টিপক।"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"এই ডিভাইচটো অতি সোনকালে অফ হ\'ব, এইটো অন ৰাখিবলৈ টিপক।"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলটো আঁতৰোৱা হ\'ব, যি কার্যই প্ৰ\'ফাইলটোৰ সকলো ডেটা মচিব।"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলটো আঁতৰোৱা হ\'ব, যিয়ে প্ৰ\'ফাইলটোৰ সকলো ডেটা মচিব।"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"আপুনি আপোনাৰ আনলক আৰ্হিটো <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। <xliff:g id="NUMBER_1">%2$d</xliff:g>তকৈ বেছি বাৰ ভুল আৰ্হি আঁকিলে আপোনাৰ টেবলেটটো কোনো একাউণ্টৰ জৰিয়তে আনলক কৰিবলৈ কোৱা হ\'ব।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ছেকেণ্ডৰ পিছত আকৌ চেষ্টা কৰক।"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"আপুনি আপোনাৰ আনলক আৰ্হিটো <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। <xliff:g id="NUMBER_1">%2$d</xliff:g>তকৈ বেছি বাৰ ভুল আৰ্হি আঁকিলে আপোনাৰ ফ\'নটো কোনো একাউণ্টৰ জৰিয়তে আনলক কৰিবলৈ কোৱা হ\'ব।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ছেকেণ্ডৰ পিছত আকৌ চেষ্টা কৰক।"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-az/strings.xml b/packages/SystemUI/res-product/values-az/strings.xml
new file mode 100644
index 0000000..c34b142
--- /dev/null
+++ b/packages/SystemUI/res-product/values-az/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Planşetdə SIM kart yoxdur."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefonda SIM kart yoxdur."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodlar uyğun gəlmir"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Planşetin kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış cəhdlər etmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra bu planşet sıfırlanacaq və bütün data silinəcək."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış cəhdlər etmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra bu telefon sıfırlanacaq və bütün data silinəcək."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Planşetin kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhdlər etmisiniz. Bu planşet sıfırlanacaq və bütün data silinəcək."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhdlər etmisiniz. Bu telefon sıfırlanacaq və bütün data silinəcək."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Planşetin kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra bu istifadəçi silinəcək və bütün istifadəçi datası ləğv ediləcək."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra bu istifadəçi silinəcək və bütün istifadəçi datası ləğv ediləcək."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV cihazı tezliklə sönəcək; aktiv saxlamaq üçün düyməyə basın."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Cihaz tezliklə sönəcək; aktiv saxlamaq üçün basın."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Planşetin kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhdlər etmisiniz. İş profili silinəcək və bütün data ləğv ediləcək."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhdlər etmisiniz. İş profili silinəcək və bütün data ləğv ediləcək."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Kilid açma modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra planşet kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Kilid açma modelini artıq <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra telefon kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..e753e74
--- /dev/null
+++ b/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"U tabletu nema SIM kartice."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"U telefonu nema SIM kartice."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodovi se ne podudaraju"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, ovaj tablet će se resetovati, čime se brišu svi podaci korisnika."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, ovaj telefon će se resetovati, čime se brišu svi podaci korisnika."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Ovaj tablet će se resetovati, čime se brišu svi podaci."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Ovaj telefon će se resetovati, čime se brišu svi podaci."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, uklonićemo ovog korisnika, čime se brišu svi podaci korisnika."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV će se uskoro isključiti. Pritisnite dugme da bi ostao uključen."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Uređaj će se uskoro isključiti. Pritisnite da bi ostao uključen."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Pogrešno ste pokušali da otključate tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo profil za Work, čime se brišu svi podaci sa profila."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo profil za Work, čime se brišu svi podaci sa profila."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, zatražićemo da otključate tablet pomoću imejl naloga.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, zatražićemo da otključate telefon pomoću imejl naloga.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-be/strings.xml b/packages/SystemUI/res-product/values-be/strings.xml
new file mode 100644
index 0000000..e2dbd24
--- /dev/null
+++ b/packages/SystemUI/res-product/values-be/strings.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"У планшэце няма SIM-карты."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"У тэлефоне няма SIM-карты."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-коды не супадаюць"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Вы не змаглі разблакіраваць планшэт столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) ён будзе скінуты да заводскіх налад, гэта прывядзе да выдалення ўсіх даных."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Вы не змаглі разблакіраваць тэлефон столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) ён будзе скінуты да заводскіх налад, гэта прывядзе да выдалення ўсіх даных."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Вы не змаглі разблакіраваць планшэт столькі разоў: <xliff:g id="NUMBER">%d</xliff:g>. Цяпер ён будзе скінуты да заводскіх налад, гэта прывядзе да выдалення ўсіх даных."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Вы не змаглі разблакіраваць тэлефон столькі разоў: <xliff:g id="NUMBER">%d</xliff:g>. Цяпер ён будзе скінуты да заводскіх налад, гэта прывядзе да выдалення ўсіх даных."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Вы не змаглі разблакіраваць планшэт столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) гэты карыстальнік будзе выдалены, гэта прывядзе да выдалення ўсіх карыстальніцкіх даных."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Вы не змаглі разблакіраваць тэлефон столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) гэты карыстальнік будзе выдалены, гэта прывядзе да выдалення ўсіх карыстальніцкіх даных."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (5143715405241138822) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Прылада Android TV неўзабаве выключыцца. Каб пакінуць яе ўключанай, націсніце кнопку."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Прылада неўзабаве выключыцца. Націсніце, каб пакінуць яе ўключанай."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Вы не змаглі разблакіраваць планшэт столькі разоў: <xliff:g id="NUMBER">%d</xliff:g>. Працоўны профіль будзе выдалены, гэта прывядзе да выдалення ўсіх даных у профілі."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Вы не змаглі разблакіраваць тэлефон столькі разоў: <xliff:g id="NUMBER">%d</xliff:g>. Працоўны профіль будзе выдалены, гэта прывядзе да выдалення ўсіх даных у профілі."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Вы няправільна ўвялі ўзор разблакіроўкі столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) вам будзе прапанавана разблакіраваць планшэт, увайшоўшы ва ўліковы запіс электроннай пошты.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Вы няправільна ўвялі ўзор разблакіроўкі столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) вам будзе прапанавана разблакіраваць тэлефон, увайшоўшы ва ўліковы запіс электроннай пошты.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-bg/strings.xml b/packages/SystemUI/res-product/values-bg/strings.xml
new file mode 100644
index 0000000..4ae6d4c
--- /dev/null
+++ b/packages/SystemUI/res-product/values-bg/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"В таблета няма SIM карта."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"В телефона няма SIM карта."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ПИН кодовете не съвпадат"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Опитахте да отключите таблета и сбъркахте <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита той ще бъде нулиран, при което ще се изтрият всичките му данни."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Опитахте да отключите телефона и сбъркахте <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита той ще бъде нулиран, при което ще се изтрият всичките му данни."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Опитахте да отключите таблета и сбъркахте <xliff:g id="NUMBER">%d</xliff:g> пъти. Той ще бъде нулиран, при което ще се изтрият всичките му данни."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Опитахте да отключите телефона и сбъркахте <xliff:g id="NUMBER">%d</xliff:g> пъти. Той ще бъде нулиран, при което ще се изтрият всичките му данни."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Опитахте да отключите таблета и сбъркахте <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита този потребител ще бъде премахнат, при което ще се изтрият всички данни за него."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Опитахте да отключите телефона и сбъркахте <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита този потребител ще бъде премахнат, при което ще се изтрият всички данни за него."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Устройството с Android TV скоро ще се изключи. Натиснете бутон, за да остане включено."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Устройството скоро ще се изключи. Натиснете, за да остане включено."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Опитахте да отключите таблета и сбъркахте <xliff:g id="NUMBER">%d</xliff:g> пъти. Служебният потребителски профил ще бъде премахнат, при което ще се изтрият всички данни за него."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Опитахте да отключите телефона и сбъркахте <xliff:g id="NUMBER">%d</xliff:g> пъти. Служебният потребителски профил ще бъде премахнат, при което ще се изтрият всички данни за него."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета си посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-bn/strings.xml b/packages/SystemUI/res-product/values-bn/strings.xml
new file mode 100644
index 0000000..260f7bc
--- /dev/null
+++ b/packages/SystemUI/res-product/values-bn/strings.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ট্যাবলেটের মধ্যে কোনো সিম কার্ড নেই।"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ফোনের মধ্যে কোনো সিম কার্ড নেই।"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"পিন কোডগুলি মিলছে না"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ট্যাবলেটটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ফোনটি আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ফোনটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুলভাবে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন। এই ফোনটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুলভাবে ফোনটি আনলক করার চেষ্টা করেছেন। এই ফোনটিকে রিসেট করা হবে, যার ফলে এর সমস্ত ডেটা মুছে যাবে।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ব্যবহারকারীকে সরিয়ে দেওয়া হবে, যার ফলে ব্যবহারকারীর সমস্ত ডেটা মুছে যাবে।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে ফোনটি আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর এই ব্যবহারকারীকে সরিয়ে দেওয়া হবে, যার ফলে ব্যবহারকারীর সমস্ত ডেটা মুছে যাবে।"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for notification_bubble_title (8330481035191903164) -->
+ <skip/>
+ <!-- no translation found for notification_channel_summary_bubble (7235935211580860537) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ডিভাইস শীঘ্রই বন্ধ হয়ে যাবে, চালু রাখতে বোতাম প্রেস করুন।"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ডিভাইস শীঘ্রই বন্ধ হয়ে যাবে, চালু রাখতে প্রেস করুন।"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুলভাবে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন। কাজের প্রোফাইলটি সরিয়ে দেওয়া হবে, যার ফলে প্রোফাইলের সমস্ত ডেটা মুছে যাবে।"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুলভাবে ফোনটি আনলক করার চেষ্টা করেছেন। কাজের প্রোফাইলটি সরিয়ে দেওয়া হবে, যার ফলে প্রোফাইলের সমস্ত ডেটা মুছে যাবে।"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আনলকের প্যাটার্ন এঁকেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর আপনাকে একটি ইমেল অ্যাকাউন্টের মাধ্যমে আপনার ট্যাবলেটটি আনলক করতে বলা হবে।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আনলকের প্যাটার্ন এঁকেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টার পর আপনাকে একটি ইমেল অ্যাকাউন্টের মাধ্যমে আপনার ফোনটি আনলক করতে বলা হবে।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-bs/strings.xml b/packages/SystemUI/res-product/values-bs/strings.xml
new file mode 100644
index 0000000..b9beecf
--- /dev/null
+++ b/packages/SystemUI/res-product/values-bs/strings.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nema SIM kartice u tabletu."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Nema SIM kartice u telefonu."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-ovi se ne poklapaju"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati tablet. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, tablet će se vratiti na fabričke postavke i svi podaci će se izbrisati."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati telefon. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, telefon će se vratiti na fabričke postavke i svi podaci će se izbrisati."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati tablet. Tablet će se sada vratiti na fabričke postavke i svi podaci će se izbrisati."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati telefon. Telefon će se sada vratiti na fabričke postavke i svi podaci će se izbrisati."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati tablet. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, ovaj korisnik će se ukloniti i svi podaci korisnika će se izbrisati."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati telefon. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, ovaj korisnik će se ukloniti i svi podaci korisnika će se izbrisati."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for volume_stream_content_description_unmute (7729576371406792977) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV uređaj će se uskoro isključiti. Pritisnite dugme da ostane uključen."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Uređaj će se uskoro isključiti. Pritisnite da ostane uključen."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati tablet. Poslovni profil će se ukloniti i svi podaci s profila će se izbrisati."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati telefon. Poslovni profil će se ukloniti i svi podaci s profila će se izbrisati."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da tablet otključate koristeći račun e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da telefon otključate koristeći račun e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ca/strings.xml b/packages/SystemUI/res-product/values-ca/strings.xml
new file mode 100644
index 0000000..20d8e2f
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ca/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No hi ha cap SIM a la tauleta."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No hi ha cap SIM al telèfon."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Els codis PIN no coincideixen"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, la tauleta es restablirà i se\'n suprimiran totes les dades."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, el telèfon es restablirà i se\'n suprimiran totes les dades."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. La tauleta es restablirà i se\'n suprimiran totes les dades."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. El telèfon es restablirà i se\'n suprimiran totes les dades."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, l\'usuari se suprimirà, juntament amb totes les seves dades."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, l\'usuari se suprimirà, juntament amb totes les seves dades."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"El dispositiu Android TV s\'apagarà aviat; prem un botó per mantenir-lo encès."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"El dispositiu s\'apagarà aviat; prem per mantenir-lo encès."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. El perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. El perfil professional se suprimirà, juntament amb totes les dades que contingui."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-cs/strings.xml b/packages/SystemUI/res-product/values-cs/strings.xml
new file mode 100644
index 0000000..feb3d95
--- /dev/null
+++ b/packages/SystemUI/res-product/values-cs/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"V tabletu není SIM karta."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"V telefonu není SIM karta."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kódy PIN se neshodují"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Již jste se <xliff:g id="NUMBER_0">%1$d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech bude tablet resetován, čímž se z něj smažou všechna data."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Již jste se <xliff:g id="NUMBER_0">%1$d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech bude telefon resetován, čímž se z něj smažou všechna data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Tablet bude resetován, čímž z něj budou smazána všechna data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Telefon bude resetován, čímž z něj budou smazána všechna data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Již jste se <xliff:g id="NUMBER_0">%1$d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech bude tento uživatel odstraněn, čímž se smažou všechna jeho data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Již jste se <xliff:g id="NUMBER_0">%1$d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech bude tento uživatel odstraněn, čímž se smažou všechna jeho data."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Zařízení Android TV se brzy vypne, stisknutím tlačítka ho ponecháte zapnuté."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Zařízení se brzy vypne, stisknutím ho ponecháte zapnuté."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Pracovní profil bude odstraněn, čímž budou smazána všechna jeho data."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Pracovní profil bude odstraněn, čímž budou smazána všechna jeho data."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali své bezpečnostní gesto. Po <xliff:g id="NUMBER_1">%2$d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali své bezpečnostní gesto. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-da/strings.xml b/packages/SystemUI/res-product/values-da/strings.xml
new file mode 100644
index 0000000..0a7135c
--- /dev/null
+++ b/packages/SystemUI/res-product/values-da/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Der er ikke noget SIM-kort i denne tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Der er ikke noget SIM-kort i telefonen."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Pinkoderne stemmer ikke overens"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Du har forsøgt at låse denne tablet op med den forkerte adgangskode <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg nulstilles denne tablet, hvilket sletter alle dens data."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Du har forsøgt at låse telefonen op med den forkerte adgangskode <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg nulstilles denne telefon, hvilket sletter alle dens data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Du har forsøgt at låse denne tablet op på forkert vis <xliff:g id="NUMBER">%d</xliff:g> gange. Denne tablet nulstilles, hvilket sletter alle dens data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Du har forsøgt at låse telefonen op på forkert vis <xliff:g id="NUMBER">%d</xliff:g> gange. Telefonen nulstilles, hvilket sletter alle dens data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Du har forsøgt at låse denne tablet op med den forkerte adgangskode <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg fjernes denne bruger, hvilket sletter alle brugerdata."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Du har forsøgt at låse telefonen op med den forkerte adgangskode <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg fjernes denne bruger, hvilket sletter alle brugerdata."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV-enheden slukker snart. Tryk på en knap for at holde den tændt."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Enheden slukker snart. Tryk for at holde den tændt."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Du har forsøgt at låse denne tablet op på forkert vis <xliff:g id="NUMBER">%d</xliff:g> gange. Arbejdsprofilen fjernes, hvilket sletter alle profildata."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Du har forsøgt at låse telefonen op på forkert vis <xliff:g id="NUMBER">%d</xliff:g> gange. Arbejdsprofilen fjernes, hvilket sletter alle profildata."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg bliver du bedt om at låse din tablet op ved hjælp af en mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg bliver du bedt om at låse din telefon op ved hjælp af en mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-de/strings.xml b/packages/SystemUI/res-product/values-de/strings.xml
new file mode 100644
index 0000000..0c0c513
--- /dev/null
+++ b/packages/SystemUI/res-product/values-de/strings.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Keine SIM-Karte im Tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Keine SIM-Karte im Telefon."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-Codes stimmen nicht überein"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieses Tablet zurückgesetzt. Dadurch werden alle Gerätedaten gelöscht."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieses Telefon zurückgesetzt. Dadurch werden alle Gerätedaten gelöscht."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Dieses Tablet wird nun zurückgesetzt und alle Gerätedaten werden gelöscht."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Dieses Telefon wird nun zurückgesetzt und alle Gerätedaten werden gelöscht."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieser Nutzer entfernt. Dadurch werden alle Nutzerdaten gelöscht."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieser Nutzer entfernt. Dadurch werden alle Nutzerdaten gelöscht."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (5143715405241138822) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level_charging (8892191177774027364) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Das Android TV-Gerät wird demnächst abgeschaltet. Drücke eine Taste, damit es eingeschaltet bleibt."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Das Gerät wird demnächst abgeschaltet. Drücke beispielsweise eine Taste oder berühre den Bildschirm, damit es eingeschaltet bleibt."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Arbeitsprofil wird nun entfernt und alle Profildaten werden gelöscht."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Das Arbeitsprofil wird nun entfernt und alle Profildaten werden gelöscht."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Tablet mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Telefon mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-el/strings.xml b/packages/SystemUI/res-product/values-el/strings.xml
new file mode 100644
index 0000000..cd76dac
--- /dev/null
+++ b/packages/SystemUI/res-product/values-el/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Δεν υπάρχει κάρτα SIM στο tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Δεν υπάρχει κάρτα SIM στο τηλέφωνο."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Δεν υπάρχει αντιστοιχία μεταξύ των κωδικών PIN"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Δοκιμάσατε να ξεκλειδώσετε το tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές χωρίς επιτυχία. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, αυτό το tablet θα ρυθμιστεί εκ νέου και θα διαγραφούν όλα τα δεδομένα του."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Δοκιμάσατε να ξεκλειδώσετε το τηλέφωνο <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές χωρίς επιτυχία. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, αυτό το τηλέφωνο θα ρυθμιστεί εκ νέου και θα διαγραφούν όλα τα δεδομένα του."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Δοκιμάσατε να ξεκλειδώσετε αυτό το tablet <xliff:g id="NUMBER">%d</xliff:g> φορές χωρίς επιτυχία. Αυτό το tablet θα ρυθμιστεί εκ νέου και θα διαγραφούν όλα τα δεδομένα του."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Δοκιμάσατε να ξεκλειδώσετε το τηλέφωνο <xliff:g id="NUMBER">%d</xliff:g> φορές χωρίς επιτυχία. Αυτό το τηλέφωνο θα ρυθμιστεί εκ νέου και θα διαγραφούν όλα τα δεδομένα του."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Δοκιμάσατε να ξεκλειδώσετε το tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές χωρίς επιτυχία. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, αυτός ο χρήστης θα καταργηθεί και θα διαγραφούν όλα τα δεδομένα χρήστη."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Δοκιμάσατε να ξεκλειδώσετε το τηλέφωνο <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές χωρίς επιτυχία. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, αυτός ο χρήστης θα καταργηθεί και θα διαγραφούν όλα τα δεδομένα χρήστη."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Η συσκευή Android TV σύντομα θα απενεργοποιηθεί. Πατήστε ένα κουμπί για να την κρατήσετε ενεργοποιημένη."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Η συσκευή σύντομα θα απενεργοποιηθεί. Πατήστε για να την κρατήσετε ενεργοποιημένη."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Δοκιμάσατε να ξεκλειδώσετε το tablet <xliff:g id="NUMBER">%d</xliff:g> φορές χωρίς επιτυχία. Το προφίλ εργασίας θα καταργηθεί και θα διαγραφούν όλα τα δεδομένα προφίλ."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Δοκιμάσατε να ξεκλειδώσετε το τηλέφωνο <xliff:g id="NUMBER">%d</xliff:g> φορές χωρίς επιτυχία. Το προφίλ εργασίας θα καταργηθεί και θα διαγραφούν όλα τα δεδομένα προφίλ."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, θα σας ζητηθεί να ξεκλειδώσετε το tablet με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%3$d</xliff:g> δευτερόλεπτα."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%3$d</xliff:g> δευτερόλεπτα."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-en-rAU/strings.xml b/packages/SystemUI/res-product/values-en-rAU/strings.xml
new file mode 100644
index 0000000..9e8ed2f
--- /dev/null
+++ b/packages/SystemUI/res-product/values-en-rAU/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No SIM card in tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No SIM card in phone."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN codes do not match"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"The Android TV device will soon turn off; press a button to keep it on."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"The device will soon turn off; press to keep it on."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-en-rCA/strings.xml b/packages/SystemUI/res-product/values-en-rCA/strings.xml
new file mode 100644
index 0000000..9e8ed2f
--- /dev/null
+++ b/packages/SystemUI/res-product/values-en-rCA/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No SIM card in tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No SIM card in phone."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN codes do not match"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"The Android TV device will soon turn off; press a button to keep it on."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"The device will soon turn off; press to keep it on."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-en-rGB/strings.xml b/packages/SystemUI/res-product/values-en-rGB/strings.xml
new file mode 100644
index 0000000..9e8ed2f
--- /dev/null
+++ b/packages/SystemUI/res-product/values-en-rGB/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No SIM card in tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No SIM card in phone."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN codes do not match"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"The Android TV device will soon turn off; press a button to keep it on."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"The device will soon turn off; press to keep it on."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-en-rIN/strings.xml b/packages/SystemUI/res-product/values-en-rIN/strings.xml
new file mode 100644
index 0000000..9e8ed2f
--- /dev/null
+++ b/packages/SystemUI/res-product/values-en-rIN/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No SIM card in tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No SIM card in phone."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN codes do not match"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"The Android TV device will soon turn off; press a button to keep it on."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"The device will soon turn off; press to keep it on."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-en-rXC/strings.xml b/packages/SystemUI/res-product/values-en-rXC/strings.xml
new file mode 100644
index 0000000..2806288
--- /dev/null
+++ b/packages/SystemUI/res-product/values-en-rXC/strings.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 accessibility_casting (8708751252897282313) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"The Android TV device will soon turn off; press a button to keep it on."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"The device will soon turn off; press to keep it on."</string>
+<string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No SIM card in tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No SIM card in phone."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN codes does not match"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="9046628517316763961">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3588779327358321092">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="6114158710353725041">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="8345451368768804892">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-es-rUS/strings.xml b/packages/SystemUI/res-product/values-es-rUS/strings.xml
new file mode 100644
index 0000000..85d3dba
--- /dev/null
+++ b/packages/SystemUI/res-product/values-es-rUS/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No hay tarjeta SIM en la tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No hay tarjeta SIM en el teléfono."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Los códigos PIN no coinciden"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Intentaste desbloquear la tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se restablecerá la tablet, lo que borrará todos los datos."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se restablecerá el teléfono, lo que borrará todos los datos."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Intentaste desbloquear la tablet <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se restablecerá la tablet, lo que borrará todos los datos."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se restablecerá el teléfono, lo que borrará todos los datos."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Intentaste desbloquear la tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se quitará este usuario, lo que borrará todos los datos asociados."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se quitará este usuario, lo que borrará todos los datos asociados."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Pronto se apagará el dispositivo Android TV; presiona un botón para mantenerlo encendido."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Pronto se apagará el dispositivo; presiona para mantenerlo encendido."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Intentaste desbloquear la tablet <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se quitará el perfil de trabajo, lo que borrará todos los datos asociados."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se quitará el perfil de trabajo, lo que borrará todos los datos asociados."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu tablet mediante una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-es/strings.xml b/packages/SystemUI/res-product/values-es/strings.xml
new file mode 100644
index 0000000..ed94cb2
--- /dev/null
+++ b/packages/SystemUI/res-product/values-es/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"No se ha insertado ninguna tarjeta SIM en el tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"No se ha insertado ninguna tarjeta SIM en el teléfono."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Los códigos PIN no coinciden"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al desbloquear el tablet. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, se recuperarán los ajustes de fábrica de este tablet y se eliminarán todos sus datos."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al desbloquear el teléfono. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, se recuperarán los ajustes de fábrica de este teléfono y se eliminarán todos sus datos."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Has fallado <xliff:g id="NUMBER">%d</xliff:g> veces al desbloquear el tablet. Se recuperarán los ajustes de fábrica de este tablet y se eliminarán todos sus datos."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Has fallado <xliff:g id="NUMBER">%d</xliff:g> veces al desbloquear el teléfono. Se recuperarán los ajustes de fábrica de este teléfono y se eliminarán todos sus datos."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al desbloquear el tablet. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, se quitará a este usuario y se eliminarán todos sus datos."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al desbloquear el teléfono. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, se quitará a este usuario y se eliminarán todos sus datos."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"El dispositivo Android TV pronto se apagará; pulsa un botón para evitarlo."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"El dispositivo pronto se apagará si no interactúas con él."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Has fallado <xliff:g id="NUMBER">%d</xliff:g> veces al desbloquear el tablet. Se quitará este perfil de trabajo se quitará y se eliminarán todos sus datos."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Has fallado <xliff:g id="NUMBER">%d</xliff:g> veces al desbloquear el teléfono. Se quitará este perfil de trabajo y se eliminarán todos sus datos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, tendrás que usar una cuenta de correo electrónico para desbloquear el tablet.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, tendrás que usar una cuenta de correo electrónico para desbloquear el teléfono.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-et/strings.xml b/packages/SystemUI/res-product/values-et/strings.xml
new file mode 100644
index 0000000..1c4688a
--- /dev/null
+++ b/packages/SystemUI/res-product/values-et/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Tahvelarvutis pole SIM-kaarti."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefonis pole SIM-kaarti."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-koodid ei ole vastavuses"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Olete püüdnud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset tahvelarvuti lähtestatakse ja kõik selle andmed kustutatakse."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Olete püüdnud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset telefon lähtestatakse ja kõik selle andmed kustutatakse."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Olete püüdnud <xliff:g id="NUMBER">%d</xliff:g> korda tahvelarvutit valesti avada. Tahvelarvuti lähtestatakse ja kõik selle andmed kustutatakse."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Olete püüdnud <xliff:g id="NUMBER">%d</xliff:g> korda telefoni valesti avada. Telefon lähtestatakse ja kõik selle andmed kustutatakse."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Olete püüdnud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset kasutaja eemaldatakse ja kõik kasutajaandmed kustutatakse."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Olete püüdnud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset kasutaja eemaldatakse ja kõik kasutajaandmed kustutatakse."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV seade lülitub varsti välja; selle aktiivsena hoidmiseks vajutage nuppu."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Seade lülitub värsti välja; selle aktiivsena hoidmiseks vajutage nuppu."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Olete püüdnud <xliff:g id="NUMBER">%d</xliff:g> korda tahvelarvutit valesti avada. Tööprofiil eemaldatakse ja kõik profiiliandmed kustutatakse."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Olete püüdnud <xliff:g id="NUMBER">%d</xliff:g> korda telefoni valesti avada. Tööprofiil eemaldatakse ja kõik profiiliandmed kustutatakse."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-eu/strings.xml b/packages/SystemUI/res-product/values-eu/strings.xml
new file mode 100644
index 0000000..265400a
--- /dev/null
+++ b/packages/SystemUI/res-product/values-eu/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Ez dago SIM txartelik tabletan."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Ez dago SIM txartelik telefonoan."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodeak ez datoz bat"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz saiatu zara tableta desblokeatzen, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, berrezarri egingo da tableta eta, ondorioz, bertako datu guztiak ezabatuko dira."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz saiatu zara telefonoa desblokeatzen, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, berrezarri egingo da telefonoa eta, ondorioz, bertako datu guztiak ezabatuko dira."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"<xliff:g id="NUMBER">%d</xliff:g> aldiz saiatu zara tableta desblokeatzen, baina huts egin duzu denetan. Tableta berrezarri egingo da eta, ondorioz, bertako datu guztiak ezabatuko dira."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"<xliff:g id="NUMBER">%d</xliff:g> aldiz saiatu zara telefonoa desblokeatzen, baina huts egin duzu denetan. Telefonoa berrezarri egingo da eta, ondorioz, bertako datu guztiak ezabatuko dira."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz saiatu zara tableta desblokeatzen, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, kendu egingo da erabiltzailea eta, ondorioz, haren datu guztiak ezabatuko dira."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz saiatu zara telefonoa desblokeatzen, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, kendu egingo da erabiltzailea eta, ondorioz, haren datu guztiak ezabatuko dira."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV gailua laster itzaliko da; sakatu botoi bat piztuta mantentzeko."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Gailua laster itzaliko da; sakatu piztuta mantentzeko."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"<xliff:g id="NUMBER">%d</xliff:g> aldiz saiatu zara tableta desblokeatzen, baina huts egin duzu denetan. Laneko profila kendu egingo da eta, ondorioz, profileko datu guztiak ezabatuko dira."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"<xliff:g id="NUMBER">%d</xliff:g> aldiz saiatu zara telefonoa desblokeatzen, baina huts egin duzu denetan. Laneko profila kendu egingo da eta, ondorioz, profileko datu guztiak ezabatuko dira."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz marraztu duzu desblokeatzeko eredua, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, tableta posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz marraztu duzu desblokeatzeko eredua, baina huts egin duzu denetan. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, telefonoa posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-fa/strings.xml b/packages/SystemUI/res-product/values-fa/strings.xml
new file mode 100644
index 0000000..018c17d
--- /dev/null
+++ b/packages/SystemUI/res-product/values-fa/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"سیمکارت درون رایانهٔ لوحی نیست."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"سیمکارت درون تلفن نیست."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"کدهای پین منطبق نیستند"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل رایانه لوحی داشتهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، این رایانه لوحی بازنشانی میشود که با آن همه دادههایش حذف میشود."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشتهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، تلفن بازنشانی میشود که با آن همه دادههایش حذف میشود."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل رایانه لوحی داشتهاید. این رایانه لوحی بازنشانی میشود که با آن همه دادههایش حذف میشود."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشتهاید. این تلفن بازنشانی میشود که با آن همه دادههایش حذف میشود."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل رایانه لوحی داشتهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، این کاربر پاک میشود که با آن همه دادههای کاربر حذف میشود."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشتهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، این کاربر پاک میشود که با آن همه دادههای کاربر حذف میشود."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"دستگاه Android TV بهزودی خاموش میشود، برای روشن نگهداشتن آن، دکمهای را فشار دهید."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"دستگاه بهزودی خاموش میشود، برای روشن نگهداشتن آن فشار دهید."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل رایانه لوحی داشتهاید. نمایه کاری پاک میشود که با آن همه دادههای نمایه حذف میشود."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشتهاید. نمایه کاری پاک میشود که با آن همه دادههای نمایه حذف میشود."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"شما الگوی باز کردن قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. بعد از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"شما الگوی باز کردن قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل تلفن را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-fi/strings.xml b/packages/SystemUI/res-product/values-fi/strings.xml
new file mode 100644
index 0000000..377b577
--- /dev/null
+++ b/packages/SystemUI/res-product/values-fi/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Tabletissa ei ole SIM-korttia."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Puhelimessa ei ole SIM-korttia."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-koodit eivät täsmää"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Yritit avata tabletin lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos <xliff:g id="NUMBER_1">%2$d</xliff:g> seuraavaa yritystä epäonnistuu, tämä puhelin nollataan ja kaikki sen tiedot poistetaan."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Yritit avata puhelimen lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos <xliff:g id="NUMBER_1">%2$d</xliff:g> seuraavaa yritystä epäonnistuu, tämä puhelin nollataan ja kaikki sen tiedot poistetaan."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Yritit avata tabletin lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER">%d</xliff:g> kertaa. Tämä tabletti nollataan ja kaikki sen tiedot poistetaan."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Yritit avata puhelimen lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER">%d</xliff:g> kertaa. Tämä puhelin nollataan ja kaikki sen tiedot poistetaan."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Yritit avata tabletin lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos <xliff:g id="NUMBER_1">%2$d</xliff:g> seuraavaa yritystä epäonnistuu, tämä käyttäjä ja kaikki sen käyttäjätiedot poistetaan."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Yritit avata puhelimen lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos <xliff:g id="NUMBER_1">%2$d</xliff:g> seuraavaa yritystä epäonnistuu, tämä käyttäjä ja kaikki käyttäjän tiedot poistetaan."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ‑laite sammuu pian. Pidä se päällä painamalla painiketta."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Laite sammuu pian. Pidä se päällä painamalla jotakin."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Yritit avata tabletin lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER">%d</xliff:g> kertaa. Työprofiili ja kaikki sen tiedot poistetaan."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Yritit avata puhelimen lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER">%d</xliff:g> kertaa. Työprofiili ja kaikki sen tiedot poistetaan."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään avaamaan tabletin lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään avaamaan puhelimesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-fr-rCA/strings.xml b/packages/SystemUI/res-product/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..4429937
--- /dev/null
+++ b/packages/SystemUI/res-product/values-fr-rCA/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Aucune carte SIM n\'est insérée dans la tablette."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Aucune carte SIM n\'est insérée dans le téléphone."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Les NIP ne correspondent pas."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Vous avez tenté de déverrouiller cette tablette à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> tentative(s) infructueuse(s) supplémentaire(s), cette tablette sera réinitialisée, ce qui entraînera la suppression de toutes les données qu\'elle contient."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Vous avez tenté de déverrouiller ce téléphone à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> tentative(s) infructueuse(s) supplémentaire(s), le téléphone sera réinitialisé, ce qui entraînera la suppression de toutes les données qu\'il contient."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Vous avez tenté de déverrouiller cette tablette à <xliff:g id="NUMBER">%d</xliff:g> reprises. Cette tablette sera réinitialisée, ce qui entraîne la suppression de toutes les données qu\'elle contient."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Vous avez tenté de déverrouiller ce téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Ce téléphone sera réinitialisé, ce qui entraîne la suppression de toutes les données qu\'il contient."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Vous avez tenté de déverrouiller cette tablette à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> tentative(s) infructueuse(s) supplémentaire(s), cet utilisateur sera supprimé, ce qui entraînera la suppression de toutes ses données."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Vous avez tenté de déverrouiller ce téléphone à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> tentative(s) infructueuse(s) supplémentaire(s), cet utilisateur sera supprimé, ce qui entraînera la suppression de toutes ses données."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"L\'appareil Android TV va bientôt s\'éteindre. Appuyez sur un bouton pour le laisser allumé."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"L\'appareil va bientôt s\'éteindre. Interagissez avec lui pour le laisser allumé."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Vous avez tenté de déverrouiller cette tablette à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel sera supprimé, ce qui entraîne la suppression de toutes ses données."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Vous avez tenté de déverrouiller ce téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel sera supprimé, ce qui entraîne la suppression de toutes ses données."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de courriel.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de courriel.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-fr/strings.xml b/packages/SystemUI/res-product/values-fr/strings.xml
new file mode 100644
index 0000000..2838c02
--- /dev/null
+++ b/packages/SystemUI/res-product/values-fr/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Aucune carte SIM n\'est insérée dans la tablette."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Aucune carte SIM n\'est insérée dans le téléphone."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Les codes PIN ne correspondent pas"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Vous avez tenté de déverrouiller la tablette à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, elle sera réinitialisée et toutes les données qu\'elle contient seront supprimées."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Vous avez tenté de déverrouiller le téléphone à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, il sera réinitialisé et toutes les données qu\'il contient seront supprimées."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Vous avez tenté de déverrouiller la tablette à <xliff:g id="NUMBER">%d</xliff:g> reprises. Elle va être réinitialisée et toutes les données qu\'elle contient seront supprimées."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Vous avez tenté de déverrouiller le téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Il va être réinitialisé et toutes les données qu\'il contient seront supprimées."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Vous avez tenté de déverrouiller la tablette à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ce compte utilisateur et toutes les données associées seront supprimés."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Vous avez tenté de déverrouiller le téléphone à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, ce compte utilisateur et toutes les données associées seront supprimés."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"L\'appareil Android TV va bientôt passer en mode Veille. Appuyez sur un bouton pour qu\'il reste allumé."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"L\'appareil va bientôt passer en mode Veille. Appuyez dessus pour qu\'il reste allumé."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Vous avez tenté de déverrouiller la tablette à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel et toutes les données associées vont être supprimés."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Vous avez tenté de déverrouiller le téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel et toutes les données associées vont être supprimés."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\nRéessayez dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\nRéessayez dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-gl/strings.xml b/packages/SystemUI/res-product/values-gl/strings.xml
new file mode 100644
index 0000000..b1e045f
--- /dev/null
+++ b/packages/SystemUI/res-product/values-gl/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Non hai ningunha tarxeta SIM na tableta."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Non hai ningunha tarxeta SIM no teléfono."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Os códigos PIN non coinciden"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Tentaches desbloquear a tableta <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, restablecerase a tableta e, por conseguinte, eliminaranse todos os seus datos."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, restablecerase o teléfono e, por conseguinte, eliminaranse todos os seus datos."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Tentaches desbloquear a tableta <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Restablecerase a tableta e, por conseguinte, eliminaranse todos os seus datos."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Restablecerase o teléfono e, por conseguinte, eliminaranse todos os seus datos."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Tentaches desbloquear a tableta <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, quitarase este usuario e, por conseguinte, todos os datos do usuario."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, quitarase este usuario e, por conseguinte, todos os datos do usuario."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Pronto se apagará o dispositivo Android TV. Preme un botón para mantelo acendido."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Pronto se apagará o dispositivo. Tócao para mantelo acendido."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Tentaches desbloquear a tableta <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Quitarase o perfil de traballo e, por conseguinte, todos os datos do perfil."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Quitarase o perfil de traballo e, por conseguinte, todos os datos do perfil."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Debuxaches o padrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear a tableta a través dunha conta de correo electrónico.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Debuxaches o padrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear o teléfono a través dunha conta de correo electrónico.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-gu/strings.xml b/packages/SystemUI/res-product/values-gu/strings.xml
new file mode 100644
index 0000000..1a9228e
--- /dev/null
+++ b/packages/SystemUI/res-product/values-gu/strings.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ટૅબ્લેટમાં સિમ કાર્ડ નથી."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ફોનમાં સિમ કાર્ડ નથી."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"પિન કોડ મેળ ખાતા નથી"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"તમે ટૅબ્લેટને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, આ ટૅબ્લેટ ફરીથી સેટ કરવામાં આવશે, જે તેનો તમામ ડેટા કાઢી નાખશે."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"તમે ફોનને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, આ ફોન ફરીથી સેટ કરવામાં આવશે, જે તેનો તમામ ડેટા કાઢી નાખશે."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"તમે ટૅબ્લેટને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. આ ટૅબ્લેટ ફરીથી સેટ થશે, જે તેનો તમામ ડેટા કાઢી નાખશે."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"તમે ફોનને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. આ ફોન ફરીથી સેટ કરાશે, જે તેનો તમામ ડેટા કાઢી નાખશે."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"તમે ટૅબ્લેટને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસો પછી, આ વપરાશકર્તાને દૂર કરવામાં આવશે, જે તમામ વપરાશકર્તા ડેટાને કાઢી નાખશે."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"તમે ફોનને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, આ વપરાશકર્તાને દૂર કરવામાં આવશે, જે તમામ વપરાશકર્તા ડેટા કાઢી નાખશે."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for notification_bubble_title (8330481035191903164) -->
+ <skip/>
+ <!-- no translation found for notification_channel_summary_bubble (7235935211580860537) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android ટીવી ડિવાઇસ ટૂંક સમયમાં બંધ થશે; તેને ચાલુ રાખવા માટે બટન દબાવો."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ડિવાઇસ ટૂંક સમયમાં બંધ થશે; તેને ચાલુ રાખવા માટે દબાવો."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"તમે ટૅબ્લેટને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. આ કાર્યાલયની પ્રોફાઇલ દૂર કરવામાં આવશે, જે તમામ પ્રોફાઇલ ડેટાને કાઢી નાખશે."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"તમે ફોનને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. આ કાર્યાલયની પ્રોફાઇલ દૂર કરવામાં આવશે, જે તમામ પ્રોફાઇલ ડેટાને કાઢી નાખશે."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, તમને એક ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ટૅબ્લેટને અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, તમને ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને ફોન અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-hi/strings.xml b/packages/SystemUI/res-product/values-hi/strings.xml
new file mode 100644
index 0000000..7babf18
--- /dev/null
+++ b/packages/SystemUI/res-product/values-hi/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"टैबलेट में कोई SIM कार्ड नहीं है."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"फ़ोन में कोई SIM कार्ड नहीं है."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"पिन कोड का मिलान नहीं हो रहा है"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"आपने टैबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश की है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल कोशिशों के बाद, इस टैबलेट को रीसेट कर दिया जाएगा, जिससे इसका सारा डेटा हट जाएगा."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"आपने फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश की है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल कोशिशों के बाद, इस फ़ोन को रीसेट कर दिया जाएगा, जिससे इसका सारा डेटा हट जाएगा."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"आपने टैबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से कोशिश की है. इस टैबलेट को रीसेट कर दिया जाएगा, जिससे इसका सारा डेटा हट जाएगा."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"आपने फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से कोशिश की है. इस फ़ोन को रीसेट कर दिया जाएगा, जिससे इसका सारा डेटा हट जाएगा."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"आपने टैबलेट का लॉक खोलने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश की है. <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत कोशिश करने पर, इस उपयोगकर्ता को निकाल दिया जाएगा, जिससे सभी उपयोगकर्ता डेटा मिट जाएगा."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"आपने फ़ोन का लॉक खोलने के लिए <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से कोशिश की है. <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत कोशिश करने पर, इस उपयोगकर्ता को निकाल दिया जाएगा, जिससे सभी उपयोगकर्ता डेटा मिट जाएगा."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV डिवाइस जल्द ही बंद हो जाएगा. इसे चालू रखने के लिए किसी बटन को दबाएं."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"डिवाइस जल्द ही बंद हो जाएगा. इसे चालू रखने के लिए स्क्रीन पर टैप करें या किसी बटन को दबाएं."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"आपने टैबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से कोशिश की है. वर्क प्रोफ़ाइल को निकाल दिया जाएगा, जिससे सभी प्रोफ़ाइल डेटा हट जाएगा."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"आपने फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से कोशिश की है. वर्क प्रोफ़ाइल को निकाल दिया जाएगा, जिससे सभी प्रोफ़ाइल डेटा हट जाएगा."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"आपने अपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से ड्रॉ किया है. अगर आपने <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत ड्रॉ किया, तो आपसे अपने टैबलेट को किसी ईमेल खाते का इस्तेमाल करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड बाद फिर से कोशिश करें."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"आपने अपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से ड्रॉ किया है. अगर आपने <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत ड्रॉ किया, तो आपसे अपने फ़ोन को किसी ईमेल खाते का इस्तेमाल करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड बाद फिर से कोशिश करें."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-hr/strings.xml b/packages/SystemUI/res-product/values-hr/strings.xml
new file mode 100644
index 0000000..690f58a
--- /dev/null
+++ b/packages/SystemUI/res-product/values-hr/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"U tabletu nema SIM kartice."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"U telefonu nema SIM kartice."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodovi nisu jednaki"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Neuspješno ste pokušali otključati tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja tablet će se vratiti na zadano, a time će se izbrisati i svi podaci na njemu."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Neuspješno ste pokušali otključati telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja telefon će se vratiti na zadano, a time će se izbrisati i svi podaci na njemu."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Neuspješno ste pokušali otključati tablet <xliff:g id="NUMBER">%d</xliff:g> put/a. Tablet će se vratiti na zadano, a time će se izbrisati i svi podaci na njemu."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Neuspješno ste pokušali otključati telefon <xliff:g id="NUMBER">%d</xliff:g> put/a. Telefon će se vratiti na zadano, a time će se izbrisati i svi podaci na njemu."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Neuspješno ste pokušali otključati tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja taj će se korisnik ukloniti, a time će se izbrisati i svi njegovi podaci."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Neuspješno ste pokušali otključati telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja taj će se korisnik ukloniti, a time će se izbrisati i svi njegovi podaci."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Uređaj Android TV uskoro će se isključiti. Pritisnite gumb da bi ostao uključen."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Uređaj će se uskoro isključiti. Pritisnite da bi ostao uključen."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Neuspješno ste pokušali otključati tablet <xliff:g id="NUMBER">%d</xliff:g> put/a. Radni će se profil ukloniti, a time će se izbrisati i svi njegovi podaci."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Neuspješno ste pokušali otključati telefon <xliff:g id="NUMBER">%d</xliff:g> put/a. Radni će se profil ukloniti, a time će se izbrisati i svi njegovi podaci."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja morat ćete otključati tablet pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja morat ćete otključati telefon pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-hu/strings.xml b/packages/SystemUI/res-product/values-hu/strings.xml
new file mode 100644
index 0000000..26160e4
--- /dev/null
+++ b/packages/SystemUI/res-product/values-hu/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nincs SIM-kártya a táblagépben."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Nincs SIM-kártya a telefonban."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"A PIN-kódok nem egyeznek"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálkozott sikertelenül a táblagép zárolásának feloldásával. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után a rendszer visszaállítja a táblagépet, és ezzel az összes adat törlődik róla."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálkozott sikertelenül a telefon zárolásának feloldásával. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után a rendszer visszaállítja a telefont, és ezzel az összes adat törlődik róla."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálkozott sikertelenül a táblagép zárolásának feloldásával. A rendszer visszaállítja a táblagépet, és ezzel a rajta lévő összes adat törlődik."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálkozott sikertelenül a telefon zárolásának feloldásával. A rendszer visszaállítja a telefont, és ezzel a rajta lévő összes adat törlődik."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálkozott sikertelenül a táblagép zárolásának feloldásával. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után a rendszer eltávolítja a felhasználót, és ezzel a felhasználó összes adata törlődik majd."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálkozott sikertelenül a telefon zárolásának feloldásával. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után a rendszer eltávolítja a felhasználót, és ezzel a felhasználó összes adata törlődik majd."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Az Android TV eszköz hamarosan kikapcsol. Nyomja meg valamelyik gombot, hogy bekapcsolva tarthassa."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Az eszköz hamarosan kikapcsol. Nyomja meg, hogy bekapcsolva tarthassa."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálkozott sikertelenül a táblagép zárolásának feloldásával. A rendszer eltávolítja a munkaprofilt, és ezzel a profil összes adata törlődik."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálkozott sikertelenül a telefon zárolásának feloldásával. A rendszer eltávolítja a munkaprofilt, és ezzel a profil összes adata törlődik."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után e-mail-fiók használatával kell feloldania táblagépét.\n\nPróbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után e-mail-fiók használatával kell feloldania telefonját.\n\nPróbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-hy/strings.xml b/packages/SystemUI/res-product/values-hy/strings.xml
new file mode 100644
index 0000000..008ac7e
--- /dev/null
+++ b/packages/SystemUI/res-product/values-hy/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Պլանշետում SIM քարտ չկա:"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Հեռախոսում SIM քարտ չկա:"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN կոդերը չեն համընկնում"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Դուք կատարել եք պլանշետն ապակողպելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո այս պլանշետը կվերակայվի և բոլոր տվյալները կջնջվեն:"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Դուք կատարել եք հեռախոսն ապակողպելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո այս հեռախոսը կվերակայվի և բոլոր տվյալները կջնջվեն:"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Դուք կատարել եք պլանշետն ապակողպելու <xliff:g id="NUMBER">%d</xliff:g> անհաջող փորձ: Այս պլանշետը կվերակայվի և բոլոր տվյալները կջնջվեն:"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Դուք կատարել եք հեռախոսն ապակողպելու <xliff:g id="NUMBER">%d</xliff:g> անհաջող փորձ: Այս հեռախոսը կվերակայվի և բոլոր տվյալները կջնջվեն:"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Դուք կատարել եք պլանշետն ապակողպելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո այս օգտվողը կհեռացվի և օգտվողի բոլոր տվյալները կջնջվեն:"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Դուք կատարել եք հեռախոսն ապակողպելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո այս օգտվողը կհեռացվի և օգտվողի բոլոր տվյալները կջնջվեն:"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV սարքը շուտով կանջատվի: Սեղմեք որևէ կոճակ՝ միացրած թողնելու համար:"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Սարքը շուտով կանջատվի: Սեղմեք՝ միացրած թողնելու համար:"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Դուք կատարել եք պլանշետն ապակողպելու <xliff:g id="NUMBER">%d</xliff:g> անհաջող փորձ: Աշխատանքային պրոֆիլը կհեռացվի և պրոֆիլի բոլոր տվյալները կջնջվեն:"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Դուք կատարել եք հեռախոսն ապակողպելու <xliff:g id="NUMBER">%d</xliff:g> անհաջող փորձ: Աշխատանքային պրոֆիլը կհեռացվի և պրոֆիլի բոլոր տվյալները կջնջվեն:"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Դուք կատարել եք ապակողպման նախշը մուտքագրելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել պլանշետը էլփոստի հաշվի միջոցով։\n\n Խնդրում ենք փորձել կրկին <xliff:g id="NUMBER_2">%3$d</xliff:g> վայրկյանից:"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Դուք կատարել եք ապակողպման նախշը մուտքագրելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել հեռախոսը էլփոստի հաշվի միջոցով։\n\n Խնդրում ենք փորձել կրկին <xliff:g id="NUMBER_2">%3$d</xliff:g> վայրկյանից:"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-in/strings.xml b/packages/SystemUI/res-product/values-in/strings.xml
new file mode 100644
index 0000000..e87aab3
--- /dev/null
+++ b/packages/SystemUI/res-product/values-in/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Tidak ada kartu SIM dalam tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Tidak ada Kartu SIM di dalam ponsel."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kode PIN tidak cocok"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda berupaya membuka kunci tablet dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, tablet ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda berupaya membuka kunci ponsel dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, ponsel ini akan disetel ulang, sehingga semua datanya akan dihapus."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Sudah <xliff:g id="NUMBER">%d</xliff:g> kali Anda berupaya membuka kunci tablet dengan tidak benar. Tablet ini akan disetel ulang, sehingga menghapus semua datanya."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Sudah <xliff:g id="NUMBER">%d</xliff:g> kali Anda berupaya membuka kunci ponsel dengan tidak benar. Ponsel ini akan disetel ulang, sehingga menghapus semua datanya."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda berupaya membuka kunci tablet dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda berupaya membuka kunci ponsel dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Perangkat Android TV akan segera dinonaktifkan; tekan tombol untuk terus menyalakannya."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Perangkat akan segera dinonaktifkan, tekan untuk terus menyalakannya."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Sudah <xliff:g id="NUMBER">%d</xliff:g> kali Anda berupaya membuka kunci tablet dengan tidak benar. Profil kerja akan dihapus, sehingga menghapus semua data profil."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Sudah <xliff:g id="NUMBER">%d</xliff:g> kali Anda berupaya membuka kunci ponsel dengan tidak benar. Profil kerja akan dihapus, sehingga menghapus semua data profil."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, Anda akan diminta membuka kunci tablet menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka. Setelah gagal <xliff:g id="NUMBER_1">%2$d</xliff:g> kali lagi, Anda akan diminta membuka kunci ponsel menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-is/strings.xml b/packages/SystemUI/res-product/values-is/strings.xml
new file mode 100644
index 0000000..38c651a
--- /dev/null
+++ b/packages/SystemUI/res-product/values-is/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Ekkert SIM-kort í spjaldtölvunni."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Ekkert SIM-kort í símanum."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-númerin stemma ekki"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> árangurslausar tilraunir til að opna spjaldtölvuna. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður spjaldtölvan endurstillt, með þeim afleiðingum að öllum gögnum hennar verður eytt."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> árangurslausar tilraunir til að opna símann. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður síminn endurstilltur, með þeim afleiðingum að öllum gögnum hans verður eytt."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að opna spjaldtölvuna. Spjaldtölvan verður endurstillt, með þeim afleiðingum að öllum gögnum hennar verður eytt."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að opna símann. Síminn verður endurstilltur, með þeim afleiðingum að öllum gögnum hans verður eytt."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> árangurslausar tilraunir til að opna spjaldtölvuna. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður notandinn fjarlægður með þeim afleiðingum að öllum notandagögnum verður eytt."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> árangurslausar tilraunir til að opna símann. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður notandinn fjarlægður með þeim afleiðingum að öllum notandagögnum verður eytt."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV tækið slekkur á sér fljótlega. Ýttu á takka til að það slokkni ekki á því."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Tækið slekkur á sér fljótlega. Ýttu á takka til að það slokkni ekki á því."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að opna spjaldtölvuna. Vinnusniðið verður fjarlægt, með þeim afleiðingum að öllum gögnum þess verður eytt."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að opna símann. Vinnusniðið verður fjarlægt, með þeim afleiðingum að öllum gögnum þess verður eytt."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður þú beðin(n) um að opna spjaldtölvuna með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verðurðu beðin(n) um að opna símann með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-it/strings.xml b/packages/SystemUI/res-product/values-it/strings.xml
new file mode 100644
index 0000000..1ca5706
--- /dev/null
+++ b/packages/SystemUI/res-product/values-it/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nessuna scheda SIM presente nel tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Nessuna scheda SIM presente nel telefono."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"I codici PIN non corrispondono"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Hai tentato di sbloccare il tablet senza riuscirci per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, il tablet verrà ripristinato e verranno quindi eliminati tutti i relativi dati."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Hai tentato di sbloccare il telefono senza riuscirci per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, il telefono verrà ripristinato e verranno quindi eliminati tutti i relativi dati."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Hai tentato di sbloccare il tablet senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Il tablet verrà ripristinato e verranno quindi eliminati tutti i relativi dati."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Hai tentato di sbloccare il telefono senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Il telefono verrà ripristinato e verranno quindi eliminati tutti i relativi dati."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Hai tentato di sbloccare il tablet senza riuscirci per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, questo utente verrà rimosso e verranno quindi eliminati tutti i dati associati."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Hai tentato di sbloccare il telefono senza riuscirci per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, questo utente verrà rimosso e verranno quindi eliminati tutti i dati associati."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"A breve il dispositivo Android TV si spegnerà. Premi un pulsante per tenerlo acceso."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"A breve il dispositivo si spegnerà. Premi per tenerlo acceso."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Hai tentato di sbloccare il tablet senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Il profilo di lavoro verrà rimosso e verranno quindi eliminati tutti i dati associati."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Hai tentato di sbloccare il telefono senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Il profilo di lavoro verrà rimosso e verranno quindi eliminati tutti i dati associati."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-iw/strings.xml b/packages/SystemUI/res-product/values-iw/strings.xml
new file mode 100644
index 0000000..3a6f6f1
--- /dev/null
+++ b/packages/SystemUI/res-product/values-iw/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"אין כרטיס SIM בטאבלט."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"אין כרטיס SIM בטלפון."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"קודי הגישה אינם תואמים"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, טאבלט זה יאופס וכל הנתונים שבו יימחקו."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, טלפון זה יאופס וכל הנתונים שבו יימחקו."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER">%d</xliff:g> פעמים. הטאבלט יאופס וכל הנתונים שלו יימחקו."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. הטלפון יאופס וכל הנתונים שבו יימחקו."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, משתמש זה יוסר וכל נתוני המשתמש יימחקו."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, משתמש זה יוסר וכל נתוני המשתמש יימחקו."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"מכשיר Android TV ייכבה בקרוב. יש ללחוץ על לחצן כלשהו כדי שהוא ימשיך לפעול."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"המכשיר ייכבה בקרוב, יש ללחוץ כדי שהוא ימשיך לפעול."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ניסית לבטל את נעילת הטאבלט <xliff:g id="NUMBER">%d</xliff:g> פעמים. פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון אימייל.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון אימייל.\n\n נסה שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ja/strings.xml b/packages/SystemUI/res-product/values-ja/strings.xml
new file mode 100644
index 0000000..b0ea11c
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ja/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"タブレットに SIM カードが挿入されていません。"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"スマートフォンに SIM カードが挿入されていません。"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN コードが一致しません"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"タブレットのロック解除に <xliff:g id="NUMBER_0">%1$d</xliff:g> 回失敗しました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回失敗すると、このタブレットはリセットされ、データはすべて消去されます。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"スマートフォンのロック解除に <xliff:g id="NUMBER_0">%1$d</xliff:g> 回失敗しました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回失敗すると、このスマートフォンはリセットされ、データはすべて消去されます。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"タブレットのロック解除に <xliff:g id="NUMBER">%d</xliff:g> 回失敗しました。このタブレットはリセットされ、データはすべて消去されます。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"スマートフォンのロック解除に <xliff:g id="NUMBER">%d</xliff:g> 回失敗しました。このスマートフォンはリセットされ、データはすべて消去されます。"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"タブレットのロック解除に <xliff:g id="NUMBER_0">%1$d</xliff:g> 回失敗しました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回失敗すると、このユーザーは削除され、ユーザー データはすべて消去されます。"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"スマートフォンのロック解除に <xliff:g id="NUMBER_0">%1$d</xliff:g> 回失敗しました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回失敗すると、このユーザーは削除され、ユーザー データはすべて消去されます。"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV デバイスはまもなく OFF になります。ON 状態を維持するには、ボタンを押してください。"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"このデバイスはまもなく OFF になります。ON 状態を維持するには、ボタンを押してください。"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"タブレットのロック解除に <xliff:g id="NUMBER">%d</xliff:g> 回失敗しました。仕事用プロファイルは削除され、プロファイルのデータはすべて消去されます。"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"スマートフォンのロック解除に <xliff:g id="NUMBER">%d</xliff:g> 回失敗しました。仕事用プロファイルは削除され、プロファイルのデータはすべて消去されます。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ロック解除パターンの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回間違えると、タブレットのロック解除にメール アカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後にもう一度お試しください。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ロック解除パターンの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回間違えると、スマートフォンのロック解除にメール アカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後にもう一度お試しください。"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ka/strings.xml b/packages/SystemUI/res-product/values-ka/strings.xml
new file mode 100644
index 0000000..1f5a202
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ka/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ტაბლეტში არ არის SIM ბარათი."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ტელეფონში არ არის SIM ბარათი."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-კოდები არ ემთხვევა"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"თქვენ არასწორად ცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ამ ტაბლეტის გადაყენება განხორციელდება, რაც მისი მონაცემების მთლიანად წაშლას გამოიწვევს."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"თქვენ არასწორად ცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ამ ტელეფონის გადაყენება განხორციელდება, რაც მისი მონაცემების მთლიანად წაშლას გამოიწვევს."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"თქვენ არასწორად ცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER">%d</xliff:g>-ჯერ. ამის გამო, ამ ტაბლეტის გადაყენება განხორციელდება, რაც მისი მონაცემების მთლიანად წაშლას გამოიწვევს."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"თქვენ არასწორად ცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER">%d</xliff:g>-ჯერ. ამის გამო, ამ ტელეფონის გადაყენება განხორციელდება, რაც მისი მონაცემების მთლიანად წაშლას გამოიწვევს."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"თქვენ არასწორად ცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ეს მომხმარებელი ამოიშლება, რაც მომხმარებლის ყველა მონაცემის წაშლას გამოიწვევს."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"თქვენ არასწორად ცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ეს მომხმარებელი ამოიშლება, რაც მომხმარებლის ყველა მონაცემის წაშლას გამოიწვევს."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV მოწყობილობა მალე გამოირთვება, დააჭირეთ ღილაკს, რომ ჩართული დარჩეს."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"მოწყობილობა მალე გამოირთვება, დააჭირეთ, რომ ჩართული დარჩეს."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"თქვენ არასწორად ცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER">%d</xliff:g>-ჯერ. ამის გამო, სამსახურის პროფილი ამოიშლება, რაც პროფილის ყველა მონაცემის წაშლას გამოიწვევს."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"თქვენ არასწორად ცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER">%d</xliff:g>-ჯერ. ამის გამო, სამსახურის პროფილი ამოიშლება, რაც პროფილის ყველა მონაცემის წაშლას გამოიწვევს."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ტაბლეტის განბლოკვა თქვენი ელფოსტის ანგარიშის მეშვეობით მოგიწევთ.\n\n ცადეთ ხელახლა <xliff:g id="NUMBER_2">%3$d</xliff:g> წამში."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ტელეფონის განბლოკვა თქვენი ელფოსტის ანგარიშის მეშვეობით მოგიწევთ.\n\n ცადეთ ხელახლა <xliff:g id="NUMBER_2">%3$d</xliff:g> წამში."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-kk/strings.xml b/packages/SystemUI/res-product/values-kk/strings.xml
new file mode 100644
index 0000000..8185a16
--- /dev/null
+++ b/packages/SystemUI/res-product/values-kk/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Планшетте SIM картасы жоқ."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Телефонда SIM картасы жоқ."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN коды сәйкес келмейді"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Планшет құлпын ашуға <xliff:g id="NUMBER_0">%1$d</xliff:g> рет сәтсіз әрекет жасалды. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін осы планшет бастапқы күйіне қайтарылып, оның бүкіл деректері жойылады."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Телефон құлпын ашуға <xliff:g id="NUMBER_0">%1$d</xliff:g> рет сәтсіз әрекет жасалды. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін осы телефон бастапқы күйіне қайтарылып, оның бүкіл деректері жойылады."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Планшет құлпын ашуға <xliff:g id="NUMBER">%d</xliff:g> рет сәтсіз әрекет жасалды. Осы планшет бастапқы күйіне қайтарылып, оның бүкіл деректері жойылады."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Телефон құлпын ашуға <xliff:g id="NUMBER">%d</xliff:g> рет сәтсіз әрекет жасалды. Осы телефон бастапқы күйіне қайтарылып, оның бүкіл деректері жойылады."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Планшет құлпын ашуға <xliff:g id="NUMBER_0">%1$d</xliff:g> рет сәтсіз әрекет жасалды. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін пайдаланушы өшіріліп, оның бүкіл деректері жойылады."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Телефон құлпын ашуға <xliff:g id="NUMBER_0">%1$d</xliff:g> рет сәтсіз әрекет жасалды. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін пайдаланушы өшіріліп, оның бүкіл деректері жойылады."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV құрылғысы жақын арада өшеді. Оны қосулы қалдыру үшін басыңыз."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Құрылғы жақын арада өшеді. Оны қосулы қалдыру үшін басыңыз."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Планшет құлпын ашуға <xliff:g id="NUMBER">%d</xliff:g> рет сәтсіз әрекет жасалды. Жұмыс профилі өшіріліп, оның бүкіл деректері жойылады."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Телефон құлпын ашуға <xliff:g id="NUMBER">%d</xliff:g> рет сәтсіз әрекет жасалды. Жұмыс профилі өшіріліп, оның бүкіл деректері жойылады."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Құлыпты ашу өрнегі <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін планшетті есептік жазба арқылы ашу сұралады. \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Құлыпты ашу өрнегі <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін телефонды есептік жазба арқылы ашу сұралады. \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-km/strings.xml b/packages/SystemUI/res-product/values-km/strings.xml
new file mode 100644
index 0000000..1c3c7f4
--- /dev/null
+++ b/packages/SystemUI/res-product/values-km/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"គ្មានស៊ីមកាតនៅក្នុងថេប្លេតទេ។"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"គ្មានស៊ីមកាតនៅក្នុងទូរសព្ទទេ។"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"កូដ PIN មិនត្រូវគ្នាទេ"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"អ្នកបានព្យាយាមដោះសោថេប្លេតនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ ថេប្លេតនេះនឹងត្រូវបានកំណត់ឡើងវិញ ហើយវានឹងលុបទិន្នន័យរបស់វាទាំងអស់។"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"អ្នកបានព្យាយាមដោះសោទូរសព្ទនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ ទូរសព្ទនេះនឹងត្រូវបានកំណត់ឡើងវិញ ហើយវានឹងលុបទិន្នន័យរបស់វាទាំងអស់។"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"អ្នកបានព្យាយាមដោះសោថេប្លេតនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដង។ ថេប្លេតនេះនឹងត្រូវបានកំណត់ឡើងវិញ ហើយវានឹងលុបទិន្នន័យទាំងអស់របស់វា។"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"អ្នកបានព្យាយាមដោះសោទូរសព្ទនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដងហើយ។ ទូរសព្ទនេះនឹងត្រូវបានកំណត់ឡើងវិញ ហើយវានឹងលុបទិន្នន័យទាំងអស់របស់វា។"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"អ្នកបានព្យាយាមដោះសោថេប្លេតនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ អ្នកប្រើប្រាស់នេះនឹងត្រូវបានលុប ហើយវានឹងលុបទិន្នន័យរបស់អ្នកប្រើប្រាស់ទាំងអស់។"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"អ្នកបានព្យាយាមដោះសោទូរសព្ទនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ អ្នកប្រើប្រាស់នេះនឹងត្រូវបានលុប ហើយវានឹងលុបទិន្នន័យរបស់អ្នកប្រើប្រាស់ទាំងអស់។"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"ឧបករណ៍ Android TV នឹងបិទក្នុងពេលឆាប់ៗនេះ សូមចុចប៊ូតុងដើម្បីបន្តបើកឧបករណ៍។"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ឧបករណ៍នឹងបិទក្នុងពេលឆាប់ៗនេះ សូមចុចដើម្បីបន្តបើកឧបករណ៍។"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"អ្នកបានព្យាយាមដោះសោថេប្លេតនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដងហើយ។ កម្រងព័ត៌មានការងារនេះនឹងត្រូវបានលុប ហើយវានឹងលុបទិន្នន័យកម្រងព័ត៌មានទាំងអស់។"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"អ្នកបានព្យាយាមដោះសោទូរសព្ទនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដងហើយ។ កម្រងព័ត៌មានការងារនេះនឹងត្រូវបានលុប ហើយវានឹងលុបទិន្នន័យកម្រងព័ត៌មានទាំងអស់។"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"អ្នកបានគូរលំនាំដោះសោរបស់អ្នកមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ អ្នកនឹងត្រូវបានស្នើឲ្យដោះសោថេប្លេតរបស់អ្នក ដោយប្រើគណនីអ៊ីមែល។\n\n សូមព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER_2">%3$d</xliff:g> វិនាទីទៀត។"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"អ្នកបានគូរលំនាំដោះសោរបស់អ្នកមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ ប្រសិនបើការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យទេ អ្នកនឹងត្រូវបានស្នើឲ្យដោះសោទូរសព្ទរបស់អ្នក ដោយប្រើគណនីអ៊ីមែល។\n\n សូមព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER_2">%3$d</xliff:g> វិនាទីទៀត។"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-kn/strings.xml b/packages/SystemUI/res-product/values-kn/strings.xml
new file mode 100644
index 0000000..06644f4
--- /dev/null
+++ b/packages/SystemUI/res-product/values-kn/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ಪೋನ್ನಲ್ಲಿ ಯಾವುದೇ ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ಪಿನ್ ಕೋಡ್ಗಳು ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಈ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ, ಇದು ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ಫೋನ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಈ ಫೋನ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ, ಇದು ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಈ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ, ಇದು ಅದರ ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಈ ಫೋನ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ, ಇದು ಅದರ ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಈ ಬಳಕೆದಾರರನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ, ಇದು ಬಳಕೆದಾರರ ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ಫೋನ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಈ ಬಳಕೆದಾರರನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ, ಇದು ಬಳಕೆದಾರರ ಎಲ್ಲ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"ಈ Android TV ಸಾಧನವು ಶೀಘ್ರವೇ ಆಫ್ ಆಗುತ್ತದೆ; ಇದನ್ನು ಆನ್ನಲ್ಲಿಡಲು ಬಟನ್ ಅನ್ನು ಒತ್ತಿರಿ."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ಈ ಸಾಧನವು ಶೀಘ್ರವೇ ಆಫ್ ಆಗುತ್ತದೆ; ಇದನ್ನು ಆನ್ನಲ್ಲಿಡಲು ಒತ್ತಿರಿ."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ, ಇದು ಎಲ್ಲ ಪ್ರೊಫೈಲ್ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ, ಇದು ಎಲ್ಲ ಪ್ರೊಫೈಲ್ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಎಳೆದಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ನಿಮ್ಮ ಇಮೇಲ್ ಖಾತೆಯನ್ನು ಬಳಸಿ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡುವಂತೆ ನಿಮ್ಮಲ್ಲಿ ಕೇಳಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಎಳೆದಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ನಿಮ್ಮ ಇಮೇಲ್ ಖಾತೆಯನ್ನು ಬಳಸಿ ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡುವಂತೆ ನಿಮ್ಮಲ್ಲಿ ಕೇಳಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ko/strings.xml b/packages/SystemUI/res-product/values-ko/strings.xml
new file mode 100644
index 0000000..1d5152e
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ko/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"태블릿에 SIM 카드가 없습니다."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"휴대전화에 SIM 카드가 없습니다."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN 코드가 일치하지 않음"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"태블릿 잠금 해제에 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 실패했습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 태블릿이 재설정되며 모든 데이터가 삭제됩니다."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"휴대전화 잠금 해제에 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 실패했습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 휴대전화가 재설정되며 모든 데이터가 삭제됩니다."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"태블릿 잠금 해제에 <xliff:g id="NUMBER">%d</xliff:g>번 실패했습니다. 태블릿이 재설정되며 모든 데이터가 삭제됩니다."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"휴대전화 잠금 해제에 <xliff:g id="NUMBER">%d</xliff:g>번 실패했습니다. 휴대전화가 재설정되며 모든 데이터가 삭제됩니다."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"태블릿 잠금 해제에 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 실패했습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 이 사용자와 모든 사용자 데이터가 삭제됩니다."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"휴대전화 잠금 해제에 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 실패했습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 이 사용자와 모든 사용자 데이터가 삭제됩니다."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV가 곧 꺼집니다. 계속 켜 두려면 버튼을 누르세요."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"기기가 곧 꺼집니다. 계속 켜 두려면 누르세요."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"태블릿 잠금 해제에 <xliff:g id="NUMBER">%d</xliff:g>번 실패했습니다. 직장 프로필과 모든 프로필 데이터가 삭제됩니다."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"휴대전화 잠금 해제에 <xliff:g id="NUMBER">%d</xliff:g>번 실패했습니다. 직장 프로필과 모든 프로필 데이터가 삭제됩니다."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 잘못 그렸습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금 해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g>초 후에 다시 시도해 주세요."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 잘못 그렸습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>번 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금 해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g>초 후에 다시 시도해 주세요."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ky/strings.xml b/packages/SystemUI/res-product/values-ky/strings.xml
new file mode 100644
index 0000000..bc4ffa0
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ky/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Планшетте SIM-карта жок."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Телефондо SIM-карта жок."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-коддор дал келген жок"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Планшеттин кулпусун <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу ийгиликсиз аракет кылсаңыз, бул планшет баштапкы абалга келтирилип, андагы бардык дайындар жок болот."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Телефондун кулпусун <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу ийгиликсиз аракет кылсаңыз, бул телефон баштапкы абалга келтирилип, андагы бардык дайындар жок болот."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Планшеттин кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Бул планшет баштапкы абалга келтирилип, андагы бардык дайындар жок болот."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Телефондун кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес аракет жасадыңыз. Бул телефон баштапкы абалга келтирилип, андагы бардык дайындар жок болот."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Планшеттин кулпусун <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу ийгиликсиз аракет кылсаңыз, бул колдонуучу чыгарылып салынып, колдонуучунун бардык дайындары жок болот."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Телефондун кулпусун <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу ийгиликсиз аракет кылсаңыз, бул колдонуучу чыгарылып салынып, колдонуучунун бардык дайындары жок болот."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV түзмөгү жакында өчүрүлөт, аны күйүк боюнча калтыруу үчүн баскычты басыңыз."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Түзмөк жакында өчүрүлөт, күйүк боюнча калтыруу үчүн басып коюңуз."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Планшеттин кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Жумуш профили чыгарылып салынып, андагы бардык дайындар жок болот."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Телефондун кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Жумуш профили чыгарылып салынып, андагы бардык дайындар жок болот."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Сиз графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин планшетиңизди бөгөттөн электрондук почтаңыз аркылуу чыгарышыңыз талап кылынат.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайра аракеттениңиз."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Сиз графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин телефонуңузду бөгөттөн электрондук почтаңыз аркылуу чыгаруу талап кылынат.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайра аракеттениңиз."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-lo/strings.xml b/packages/SystemUI/res-product/values-lo/strings.xml
new file mode 100644
index 0000000..8d2e0f3
--- /dev/null
+++ b/packages/SystemUI/res-product/values-lo/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ບໍ່ມີຊິມກາດໃນແທັບເລັດ."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ບໍ່ມີ SIM card ໃນໂທລະສັບ."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ລະຫັດ PIN ບໍ່ກົງກັນ"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ທ່ານພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຄັ້ງ. ຫຼັງຈາກລອງບໍ່ສຳເລັດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ຄັ້ງ, ແທັບເລັດນີ້ຈະຖືກຕັ້ງຄ່າໃໝ່, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຂອງມັນ."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ທ່ານພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຄັ້ງ. ຫຼັງຈາກລອງບໍ່ສຳເລັດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ຄັ້ງ, ໂທລະສັບນີ້ຈະຖືກຕັ້ງຄ່າໃໝ່, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຂອງມັນ."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ທ່ານພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER">%d</xliff:g> ຄັ້ງ. ແທັບເລັດນີ້ຈະຖືກຕັ້ງຄ່າໃໝ່, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຂອງມັນ."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ທ່ານພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER">%d</xliff:g> ຄັ້ງ. ໂທລະສັບນີ້ຈະຖືກຕັ້ງຄ່າໃໝ່, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຂອງມັນ."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ທ່ານພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຄັ້ງ. ຫຼັງຈາກລອງບໍ່ສຳເລັດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g>ຄັ້ງ, ຜູ້ໃຊ້ນີ້ຈະຖືກເອົາອອກໄປ, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຜູ້ໃຊ້."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ທ່ານພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຄັ້ງ. ຫຼັງຈາກລອງບໍ່ສຳເລັດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ຄັ້ງ, ຜູ້ໃຊ້ນີ້ຈະຖືກເອົາອອກໄປ, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນຜູ້ໃຊ້."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"ອຸປະກອນ Android TV ຈະປິດໃນອີກບໍ່ດົນ, ກົດປຸ່ມໃດໜຶ່ງເພື່ອເປີດມັນໄວ້ຕໍ່."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ອຸປະກອນຈະປິດໃນອີກບໍ່ດົນ, ກົດເພື່ອເປີດມັນໄວ້ຕໍ່."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ທ່ານພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER">%d</xliff:g> ຄັ້ງ. ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຈະຖືກເອົາອອກໄປ, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນໂປຣໄຟລ໌."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ທ່ານພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ຖືກຕ້ອງ <xliff:g id="NUMBER">%d</xliff:g> ຄັ້ງ. ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຈະຖືກເອົາອອກໄປ, ເຊິ່ງຈະລຶບທຸກຂໍ້ມູນໂປຣໄຟລ໌."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຜິດ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບໂດຍໃຊ້ອີເມວຂອງທ່ານ.\n\n ກະລຸນາລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_2">%3$d</xliff:g> ວິນາທີ."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ເທື່ອ ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍບັນຊີອີເມວ.\n\n ລອງໃໝ່ອີກຄັ້ງໃນ <xliff:g id="NUMBER_2">%3$d</xliff:g> ວິນາທີ."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-lt/strings.xml b/packages/SystemUI/res-product/values-lt/strings.xml
new file mode 100644
index 0000000..f291681
--- /dev/null
+++ b/packages/SystemUI/res-product/values-lt/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Planšetiniame kompiuteryje nėra SIM kortelės."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefone nėra SIM kortelės."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodai nesutampa"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. nesėkmingai bandėte atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. šis planšetinis kompiuteris bus nustatytas iš naujo ir visi jo duomenys bus ištrinti."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. nesėkmingai bandėte atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. šis telefonas bus nustatytas iš naujo ir visi jo duomenys bus ištrinti."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"<xliff:g id="NUMBER">%d</xliff:g> kart. nesėkmingai bandėte atrakinti planšetinį kompiuterį. Šis planšetinis kompiuteris bus nustatytas iš naujo ir visi jo duomenys bus ištrinti."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"<xliff:g id="NUMBER">%d</xliff:g> kart. nesėkmingai bandėte atrakinti telefoną. Šis telefonas bus nustatytas iš naujo ir visi jo duomenys bus ištrinti."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. nesėkmingai bandėte atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. šis naudotojas bus pašalintas ir visi naudotojo duomenys bus ištrinti."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. nesėkmingai bandėte atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. šis naudotojas bus pašalintas ir visi naudotojo duomenys bus ištrinti."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"„Android TV“ įrenginys netrukus išsijungs. Paspauskite mygtuką, kad jis liktų įjungtas."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Įrenginys netrukus išsijungs. Paspauskite, kad jis liktų įjungtas."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"<xliff:g id="NUMBER">%d</xliff:g> kart. nesėkmingai bandėte atrakinti planšetinį kompiuterį. Darbo profilis bus pašalintas ir visi profilio duomenys bus ištrinti."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"<xliff:g id="NUMBER">%d</xliff:g> kart. nesėkmingai bandėte atrakinti telefoną. Darbo profilis bus pašalintas ir visi profilio duomenys bus ištrinti."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai nupiešėte atrakinimo piešinį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami el. pašto paskyrą.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai nupiešėte atrakinimo piešinį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami el. pašto paskyrą.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-lv/strings.xml b/packages/SystemUI/res-product/values-lv/strings.xml
new file mode 100644
index 0000000..6459e25
--- /dev/null
+++ b/packages/SystemUI/res-product/values-lv/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Planšetdatorā nav SIM kartes."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Tālrunī nav SIM kartes."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodi neatbilst."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt planšetdatoru. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) šis planšetdators tiks atiestatīts, kā arī visi planšetdatora dati tiks dzēsti."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt tālruni. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) šis tālrunis tiks atiestatīts, kā arī visi tālruņa dati tiks dzēsti."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt planšetdatoru. Šis planšetdators tiks atiestatīts, kā arī visi planšetdatora dati tiks dzēsti."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt tālruni. Šis tālrunis tiks atiestatīts, kā arī visi tālruņa dati tiks dzēsti."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt planšetdatoru. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) šis lietotājs tiks noņemts, kā arī visi lietotāja dati tiks dzēsti."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt tālruni. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) šis lietotājs tiks noņemts, kā arī visi lietotāja dati tiks dzēsti."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ierīce drīz izslēgsies. Nospiediet pogu, lai tā paliktu ieslēgta."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Ierīce drīz izslēgsies. Nospiediet, lai tā paliktu ieslēgta."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt planšetdatoru. Darba profils tiks noņemts, kā arī visi profila dati tiks dzēsti."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt tālruni. Darba profils tiks noņemts, kā arī visi profila dati tiks dzēsti."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nepareizi norādījāt atbloķēšanas kombināciju. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) planšetdators būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundes(-ēm)."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nepareizi norādījāt atbloķēšanas kombināciju. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) tālrunis būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundes(-ēm)."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-mk/strings.xml b/packages/SystemUI/res-product/values-mk/strings.xml
new file mode 100644
index 0000000..21fde4d
--- /dev/null
+++ b/packages/SystemUI/res-product/values-mk/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Во таблетот нема SIM-картичка."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Во телефонот нема SIM-картичка."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-кодовите не се совпаѓаат"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Неправилно се обидовте да го отклучите таблетот <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, таблетот ќе се ресетира, со што ќе се избришат сите негови податоци."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Неправилно се обидовте да го отклучите телефонот <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, телефонот ќе се ресетира, со што ќе се избришат сите негови податоци."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Неправилно се обидовте да го отклучите таблетот <xliff:g id="NUMBER">%d</xliff:g> пати. Овој таблет ќе се ресетира, со што ќе се избришат сите негови податоци."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Неправилно се обидовте да го отклучите телефонот <xliff:g id="NUMBER">%d</xliff:g> пати. Овој телефон ќе се ресетира, со што ќе се избришат сите негови податоци."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Неправилно се обидовте да го отклучите таблетот <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, корисникот ќе се отстрани, со што ќе се избришат сите негови податоци."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Неправилно се обидовте да го отклучите телефонот <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, корисникот ќе се отстрани, со што ќе се избришат сите податоци на корисникот."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Уредот со Android TV наскоро ќе се исклучи, притиснете копче за да остане вклучен."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Уредот наскоро ќе се исклучи, притиснете за да остане вклучен."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Неправилно се обидовте да го отклучите таблетот <xliff:g id="NUMBER">%d</xliff:g> пати. Работниот профил ќе се отстрани, со што ќе се избришат сите податоци на профилот."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Неправилно се обидовте да го отклучите телефонот <xliff:g id="NUMBER">%d</xliff:g> пати. Работниот профил ќе се отстрани, со што ќе се избришат сите податоци на профилот."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Погрешно сте ја употребиле вашата шема на отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, ќе побараме да го отклучите таблетот со сметка на е-пошта.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Погрешно сте ја употребиле вашата шема на отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, ќе побараме да го отклучите телефонот со сметка на е-пошта.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ml/strings.xml b/packages/SystemUI/res-product/values-ml/strings.xml
new file mode 100644
index 0000000..c39cce1
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ml/strings.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ടാബ്ലെറ്റിൽ സിം കാർഡൊന്നുമില്ല."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ഫോണിൽ സിം കാർഡൊന്നുമില്ല."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"പിൻ കോഡുകൾ പൊരുത്തപ്പെടുന്നില്ല"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി ടാബ്ലെറ്റ് അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, ഈ ടാബ്ലെറ്റ് റീസെറ്റുചെയ്യപ്പെടുകയും, അതുവഴി അതിലെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി ഫോൺ അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ ഈ ഫോൺ റീസെറ്റുചെയ്യപ്പെടുകയും, അതുവഴി അതിലെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി ടാബ്ലെറ്റ് അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. ഈ ഫോൺ റീസെറ്റുചെയ്യപ്പെടുകയും, അതുവഴി അതിലെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി ഫോൺ അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. ഈ ഫോൺ റീസെറ്റുചെയ്യപ്പെടുകയും, അതുവഴി അതിലെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി ടാബ്ലെറ്റ് അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ ഈ ഉപയോക്താവിനെ നീക്കം ചെയ്യുകയും, അതുവഴി ഉപയോക്താവിന്റെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി ഫോൺ അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ ഈ ഉപയോക്താവിനെ നീക്കം ചെയ്യുകയും, അതുവഴി ഉപയോക്താവിന്റെ എല്ലാ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for notification_bubble_title (8330481035191903164) -->
+ <skip/>
+ <!-- no translation found for notification_channel_summary_bubble (7235935211580860537) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android ടിവി ഉടൻ ഓഫാകും, ഓണാക്കി നിർത്താൻ ഒരു ബട്ടൺ അമർത്തുക."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ഉപകരണം ഉടൻ ഓഫാകും, ഓണാക്കി നിർത്താൻ അമർത്തുക."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി ടാബ്ലെറ്റ് അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. ഔദ്യോഗിക പ്രൊഫൈൽ നീക്കംചെയ്യപ്പെടുകയും, അതുവഴി എല്ലാ പ്രൊഫൈൽ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായി ഫോൺ അൺലോക്കുചെയ്യാൻ ശ്രമിച്ചു. ഔദ്യോഗിക പ്രൊഫൈൽ നീക്കംചെയ്യപ്പെടുകയും, അതുവഴി എല്ലാ പ്രൊഫൈൽ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി അൺലോക്ക് പാറ്റേൺ വരച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, ഒരു ഇമെയിൽ അക്കൗണ്ടുപയോഗിച്ച് ടാബ്ലെറ്റ് അൺലോക്കുചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> സെക്കന്റ് കഴിഞ്ഞ് വീണ്ടും ശ്രമിക്കുക."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായി അൺലോക്ക് പാറ്റേൺ വരച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, ഒരു ഇമെയിൽ അക്കൗണ്ടുപയോഗിച്ച് ഫോൺ അൺലോക്കുചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> സെക്കന്റ് കഴിഞ്ഞ് വീണ്ടും ശ്രമിക്കുക."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-mn/strings.xml b/packages/SystemUI/res-product/values-mn/strings.xml
new file mode 100644
index 0000000..32f3bf9
--- /dev/null
+++ b/packages/SystemUI/res-product/values-mn/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Таблетад SIM карт алга."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Утсанд SIM карт алга."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ПИН код тохирохгүй байна"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Та таблетын түгжээг тайлах оролдлогыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу хийлээ. Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд энэ таблетыг шинэчлэх бөгөөд бүх өгөгдөл нь устах болно."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Та утасны түгжээг тайлах оролдлогыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу хийлээ.Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд энэ утсыг шинэчлэх бөгөөд бүх өгөгдөл нь устах болно."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Та таблетын түгжээг тайлах оролдлогыг <xliff:g id="NUMBER">%d</xliff:g> удаа буруу хийлээ. Энэ таблетыг шинэчлэх бөгөөд ингэснээр бүх өгөгдөл нь устах болно."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Та утасны түгжээг тайлах оролдлогыг <xliff:g id="NUMBER">%d</xliff:g> удаа буруу хийлээ. Энэ утсыг шинэчлэх бөгөөд ингэснээр бүх өгөгдөл нь устах болно."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Та таблетын түгжээг тайлах оролдлогыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу хийсэн байна. Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд энэ хэрэглэгчийг устгах бөгөөд ингэснээр хэрэглэгчийн бүх өгөгдөл устах болно."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Та утасны түгжээг тайлах оролдлогыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу хийсэн байна. Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд энэ хэрэглэгчийг устгах бөгөөд ингэснээр хэрэглэгчийн бүх өгөгдөл устах болно."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Андройд ТВ төхөөрөмж удахгүй унтрах тул асаалттай хэвээр байлгахын тулд товчлуур дээр дарна уу."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Төхөөрөмж удахгүй унтрах тул асаалттай хэвээр байлгахын тулд дарна уу."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Та таблетын түгжээг тайлах оролдогыг <xliff:g id="NUMBER">%d</xliff:g> удаа буруу хийсэн байна. Ажлын профайлыг устгах бөгөөд ингэснээр профайлын бүх өгөгдөл устах болно."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Та утасны түгжээг тайлах оролдлогыг <xliff:g id="NUMBER">%d</xliff:g> удаа буруу хийлээ. Ажлын профайлыг устгах бөгөөд ингэснээр профайлын бүх өгөгдлийг устгах болно."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Та түгжээ тайлах загварыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд таблетынхаа түгжээг имэйл бүртгэлээрээ тайлах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Та түгжээ тайлах загварыг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. Хэрэв та дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу оруулсан тохиолдолд утасныхаа түгжээг имэйл бүртгэлээрээ тайлах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-mr/strings.xml b/packages/SystemUI/res-product/values-mr/strings.xml
new file mode 100644
index 0000000..8ef190e
--- /dev/null
+++ b/packages/SystemUI/res-product/values-mr/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"टॅबलेटमध्ये सिम कार्ड नाही."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"फोनमध्ये सिम कार्ड नाही."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"पिन कोड जुळत नाहीत"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"तुम्ही टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, हे टॅबलेट रीसेट केला जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, हा फोन रीसेट केला जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"तुम्ही टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. हे टॅबलेट रीसेट केले जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. हा फोन रीसेट केला जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"तुम्ही टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, या वापरकर्त्याला काढले जाईल, जे सर्व वापरकर्ता डेटा हटवेल."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, या वापरकर्त्याला काढले जाईल, जे सर्व वापरकर्ता डेटा हटवेल."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV डिव्हाइस लवकरच बंद होणार आहे; सुरू ठेवण्यासाठी बटण दाबा."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"डिव्हाइस लवकरच बंद होणार आहे; सुरू ठेवण्यासाठी स्क्रीनवर किंवा बटण दाबा."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"तुम्ही टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. कार्य प्रोफाइल काढली जाईल, जे सर्व प्रोफाइल डेटा हटवेल."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. कार्य प्रोफाइल काढली जाईल, जे सर्व प्रोफाइल डेटा हटवेल."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून तुमचा टॅब्लेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून तुमचा फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ms/strings.xml b/packages/SystemUI/res-product/values-ms/strings.xml
new file mode 100644
index 0000000..5443a54
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ms/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Tiada kad SIM dalam tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Tiada kad SIM dalam telefon."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kod PIN tidak sepadan"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Anda telah salah membuka kunci tablet sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, tablet ini akan ditetapkan semula sekali gus memadamkan semua data."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Anda telah salah membuka kunci telefon sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, telefon ini akan ditetapkan semula sekali gus memadamkan semua data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Anda telah salah membuka kunci tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet ini akan ditetapkan semula sekali gus memadamkan semua data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Anda telah salah membuka kunci telefon sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Telefon ini akan ditetapkan semula sekali gus memadamkan semua data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Anda telah salah membuka kunci tablet sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, pengguna ini akan dialih keluar sekali gus memadamkan semua data pengguna."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Anda telah salah membuka kunci telefon sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, pengguna ini akan dialih keluar sekali gus memadamkan semua data pengguna."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Peranti Android TV akan mati tidak lama lagi; tekan butang untuk memastikan peranti terus hidup."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Peranti akan mati tidak lama lagi; tekan untuk memastikan peranti terus hidup."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Anda telah salah membuka kunci tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Profil kerja ini akan dialih keluar sekali gus memadamkan semua data profil."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Anda telah salah membuka kunci telefon sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Profil kerja ini akan dialih keluar sekali gus memadamkan semua data profil."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, anda akan diminta membuka kunci tablet anda menggunakan akaun e-mel.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, anda akan diminta membuka kunci telefon anda menggunakan akaun e-mel.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-my/strings.xml b/packages/SystemUI/res-product/values-my/strings.xml
new file mode 100644
index 0000000..3f2891d
--- /dev/null
+++ b/packages/SystemUI/res-product/values-my/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"တက်ဘလက်ထဲတွင် ဆင်းမ်ကဒ် မရှိပါ။"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ဖုန်းထဲတွင် ဆင်းမ်ကဒ် မရှိပါ။"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ပင်နံပါတ် ကိုက်ညီမှုမရှိပါ"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"တက်ဘလက်ကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းခဲ့လျှင် ဤတက်ဘလက်ကို ပြင်ဆင်သတ်မှတ်လိုက်မည် ဖြစ်ပြီး ၎င်းအတွင်းရှိ ဒေတာများအားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ဖုန်းကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းခဲ့လျှင် ဤဖုန်းကို ပြင်ဆင်သတ်မှတ်လိုက်မည် ဖြစ်ပြီး ၎င်းအတွင်းရှိ ဒေတာများအားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"တက်ဘလက်ကို <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ ဤတက်ဘလက်ကို ပြင်ဆင်သတ်မှတ်လိုက်မည် ဖြစ်ပြီး ၎င်းအတွင်းရှိ ဒေတာများအားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ဖုန်းကို <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ ဤဖုန်းကို ပြင်ဆင်သတ်မှတ်လိုက်မည် ဖြစ်ပြီး ၎င်းအတွင်းရှိ ဒေတာများအားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"တက်ဘလက်ကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းခဲ့လျှင် ဤအသုံးပြုသူကို ဖယ်ရှားလိုက်မည်ဖြစ်ပြီး အသုံးပြုသူဒေတာများ အားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ဖုန်းကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းသွားလျှင် ဤအသုံးပြုသူကို ဖယ်ရှားလိုက်မည်ဖြစ်ပြီး အသုံးပြုသူဒေတာများ အားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV စက်သည် မကြာမီ ပိတ်သွားပါမည်၊ ဆက်ဖွင့်ထားရန် ခလုတ်တစ်ခုနှိပ်ပါ။"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"စက်သည် မကြာမီ ပိတ်သွားပါမည်၊ ဆက်ဖွင့်ထားပါ။"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"တက်ဘလက်ကို <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ အလုပ်ပရိုဖိုင်ကို ဖယ်ရှားလိုက်မည်ဖြစ်ပြီး ပရိုဖိုင်ဒေတာများ အားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ဖုန်းကို <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ အလုပ်ပရိုဖိုင်ကို ဖယ်ရှားလိုက်မည်ဖြစ်ပြီး ပရိုဖိုင်ဒေတာများ အားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"သင်သည် သင်၏ လော့ခ်ဖွင့်ခြင်းပုံစံကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ ဆွဲခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းပြီးသည့်နောက်တွင် သင့်အီးမေးလ်အကောင့်အား အသုံးပြု၍ တက်ဘလက်ကို လော့ခ်ဖွင့်ရန် တောင်းဆိုသွားပါမည်။\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"သင်သည် သင်၏ လော့ခ်ဖွင့်ခြင်းပုံစံကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ ဆွဲခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းပြီးသည့်နောက်တွင် သင့်အီးမေးလ်အကောင့်အား အသုံးပြု၍ ဖုန်းကို လော့ခ်ဖွင့်ရန် တောင်းဆိုသွားပါမည်။\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-nb/strings.xml b/packages/SystemUI/res-product/values-nb/strings.xml
new file mode 100644
index 0000000..6608b25
--- /dev/null
+++ b/packages/SystemUI/res-product/values-nb/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nettbrettet mangler SIM-kort."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefonen mangler SIM-kort."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-kodene stemmer ikke overens"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Du har gjort feil i forsøket på å låse opp nettbrettet <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Nettbrettet tilbakestilles etter <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk, noe som sletter alle dataene på nettbrettet."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Du har gjort feil i forsøket på å låse opp telefonen <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Telefonen tilbakestilles etter <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk, noe som sletter alle dataene på telefonen."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Du har gjort feil i forsøket på å låse opp nettbrettet <xliff:g id="NUMBER">%d</xliff:g> ganger. Dette nettbrettet blir tilbakestilt, og alle dataene blir slettet."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Du har gjort feil i forsøket på å låse opp telefonen <xliff:g id="NUMBER">%d</xliff:g> ganger. Denne telefonen blir tilbakestilt, og alle dataene blir slettet."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Du har gjort feil i forsøket på å låse opp nettbrettet <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Brukeren fjernes etter <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk, noe som sletter alle brukerdataene."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Du har gjort feil i forsøket på å låse opp telefonen <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Brukeren fjernes etter <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk, noe som sletter alle brukerdataene."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV-enheten slås snart av. Trykk på en knapp for å holde den på."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Enheten slås snart av. Trykk for å holde den på."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Du har gjort feil i forsøket på å låse opp nettbrettet <xliff:g id="NUMBER">%d</xliff:g> ganger. Jobbprofilen blir fjernet, og alle profildataene blir slettet."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Du har gjort feil i forsøket på å låse opp telefonen <xliff:g id="NUMBER">%d</xliff:g> ganger. Jobbprofilen blir fjernet, og alle profildataene blir slettet."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Du har tegnet opplåsingsmønsteret feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> feil forsøk blir du bedt om å låse opp nettbrettet via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Du har tegnet opplåsingsmønsteret feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> feil forsøk blir du bedt om å låse opp telefonen via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ne/strings.xml b/packages/SystemUI/res-product/values-ne/strings.xml
new file mode 100644
index 0000000..2361ac9
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ne/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ट्याब्लेटमा SIM कार्ड छैन।"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"फोनमा SIM कार्ड छैन।"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN कोडहरू मिलेनन्"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यो ट्याब्लेट यसमा भएका सबै डेटा मेटिने गरी रिसेट हुनेछ।"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यो फोन यसमा भएका सबै डेटा मेटिने गरी रिसेट हुनेछ।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। यो ट्याब्लेट यसमा भएका सबै डेटा मेटिने गरी रिसेट हुनेछ।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। यो फोन यसमा भएका सबै डेटा मेटिने गरी रिसेट हुनेछ।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यस प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यस प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV यन्त्र चाँडै निष्क्रिय हुने छ; सक्रिय राख्न कुनै बटन थिच्नुहोस्।"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"यो यन्त्र चाँडै निष्क्रिय हुने छ; सक्रिय राख्न थिच्नुहोस्।"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"तपाईं <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। कार्य प्रोफाइललाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। कार्य प्रोफाइललाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो अनलक गर्ने ढाँचा गलत रूपमा कोर्नुभयो। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, तपाईंलाई एउटा इमेल खाता प्रयोग गरेर आफ्नो ट्याब्लेट अनलक गर्न आग्रह गरिनेछ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो अनलक गर्ने ढाँचा गलत रूपमा कोर्नुभयो। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, तपाईंलाई एउटा इमेल खाता प्रयोग गरेर आफ्नो फोन अनलक गर्न आग्रह गरिनेछ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-nl/strings.xml b/packages/SystemUI/res-product/values-nl/strings.xml
new file mode 100644
index 0000000..6f71d98
--- /dev/null
+++ b/packages/SystemUI/res-product/values-nl/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Geen simkaart in tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Geen simkaart in telefoon."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Pincodes komen niet overeen"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Je hebt <xliff:g id="NUMBER_0">%1$d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt deze tablet gereset, waardoor alle gegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Je hebt <xliff:g id="NUMBER_0">%1$d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt deze telefoon gereset, waardoor alle gegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Deze tablet wordt gereset, waardoor alle gegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Deze telefoon wordt gereset, waardoor alle gegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Je hebt <xliff:g id="NUMBER_0">%1$d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt deze gebruiker verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Je hebt <xliff:g id="NUMBER_0">%1$d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt deze gebruiker verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Het Android TV-apparaat wordt binnenkort uitgeschakeld. Druk op een knop om het ingeschakeld te houden."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Het apparaat wordt binnenkort uitgeschakeld. Druk om het ingeschakeld te houden."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Het werkprofiel wordt verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Het werkprofiel wordt verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt je gevraagd je tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt je gevraagd je telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-or/strings.xml b/packages/SystemUI/res-product/values-or/strings.xml
new file mode 100644
index 0000000..a6190fc
--- /dev/null
+++ b/packages/SystemUI/res-product/values-or/strings.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ଟାବଲେଟ୍ରେ କୌଣସି SIM କାର୍ଡ ନାହିଁ।"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ଫୋନରେ କୌଣସି SIM କାର୍ଡ ନାହିଁ।"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN କୋଡ୍ ମେଳ ହେଉନାହିଁ"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ଆପଣ ଟାବଲେଟକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଭୁଲ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ଏହି ଟାବଲେଟଟି ରିସେଟ୍ ହୋଇଯିବ, ଯାହାଦ୍ୱାରା ଏହାର ସମସ୍ତ ଡାଟା ଲିଟ୍ ହୋଇଯିବ।"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ଆପଣ ଫୋନକୁ ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଭୁଲ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ଏହି ଫୋନଟି ରିସେଟ୍ ହୋଇଯିବ, ଯାହାଦ୍ୱାରା ଏହାର ସମସ୍ତ ଡାଟା ଲିଟ୍ ହୋଇଯିବ।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g> ଥର ଭୁଲ୍ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ଟାବଲେଟକୁ ରିସେଟ୍ କରାଯିବ, ଯାହାଦ୍ୱାରା ଏହାର ସମସ୍ତ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ଆପଣ ଫୋନଟି ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ୍ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ଫୋନ୍ ରିସେଟ୍ କରାଯିବ, ଯାହା ଦ୍ୱାରା ଏହାର ସମସ୍ତ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ଆପଣ ଟାବଲେଟ୍ଟିକୁ ଅନଲକ୍ କରିବା ପାଇଁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଚେଷ୍ଟା କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ୱାର୍କ ପ୍ରୋଫାଇଲ୍କୁ ବାହାର କରିଦିଆଯିବ ଏବଂ ଏହା ଦ୍ୱାରା ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ଆପଣ ଫୋନଟି ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ଏହି ୟୁଜରଙ୍କୁ ବାହାର କରିଦିଆଯିବ ଏବଂ ଏହାଦ୍ୱାରା ସମସ୍ତ ୟୁଜର୍ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for notification_bubble_title (8330481035191903164) -->
+ <skip/>
+ <!-- no translation found for notification_channel_summary_bubble (7235935211580860537) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android ଟିଭି ଡିଭାଇସ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯିବ; ଏହା ଚାଲୁ ରଖିବା ପାଇଁ ଏକ ବଟନ୍ ଦବାନ୍ତୁ।"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ଡିଭାଇସ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯିବ; ଚାଲୁ ରଖିବା ପାଇଁ ଦବାନ୍ତୁ।"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g> ଭୁଲ୍ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। କାର୍ଯ୍ୟ ପ୍ରୋଫାଇଲ୍ ବାହାର କରିଦିଆଯିବ, ଯାହାଦ୍ୱାରା ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ଆପଣ ଫୋନଟି ଅନଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ୍ ଭାବେ ପ୍ରୟାସ କରିଛନ୍ତି। ୱର୍କ ପ୍ରୋଫାଇଲ୍ ବାହାର କରିଦିଆଯିବ, ଯାହା ଦ୍ୱାରା ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ଆପଣଙ୍କ ଅନଲକ୍ ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଟି ଭୁଲ ପ୍ରୟାସ ପରେ ଏକ ଇମେଲ୍ ଆକାଉଣ୍ଟ ବ୍ୟବହାର କରି ନିଜ ଟାବଲେଟକୁ ଅନଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ଆପଣଙ୍କ ଅନଲକ୍ ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଟି ଭୁଲ ପ୍ରୟାସ ପରେ ଏକ ଇମେଲ୍ ଆକାଉଣ୍ଟ ବ୍ୟବହାର କରି ନିଜ ଫୋନକୁ ଅନଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-pa/strings.xml b/packages/SystemUI/res-product/values-pa/strings.xml
new file mode 100644
index 0000000..bc16b5a
--- /dev/null
+++ b/packages/SystemUI/res-product/values-pa/strings.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ਟੈਬਲੈੱਟ ਵਿੱਚ ਕੋਈ ਸਿਮ ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ।"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ਫ਼ੋਨ ਵਿੱਚ ਕੋਈ ਸਿਮ ਕਾਰਡ ਮੌਜੂਦ ਨਹੀਂ।"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"ਪਿੰਨ ਕੋਡ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਹ ਟੈਬਲੈੱਟ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਹ ਫ਼ੋਨ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਇਹ ਟੈਬਲੈੱਟ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਇਹ ਫ਼ੋਨ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇਸਦਾ ਸਾਰਾ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਸਾਰਾ ਵਰਤੋਂਕਾਰ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਸਾਰਾ ਵਰਤੋਂਕਾਰ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for notification_bubble_title (8330481035191903164) -->
+ <skip/>
+ <!-- no translation found for notification_channel_summary_bubble (7235935211580860537) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ਡੀਵਾਈਸ ਜਲਦ ਹੀ ਬੰਦ ਹੋ ਜਾਵੇਗਾ; ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣ ਲਈ ਕੋਈ ਬਟਨ ਦਬਾਓ।"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ਡੀਵਾਈਸ ਜਲਦ ਹੀ ਬੰਦ ਹੋ ਜਾਵੇਗਾ, ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਸਾਰਾ ਪ੍ਰੋਫਾਈਲ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਸਾਰਾ ਪ੍ਰੋਫਾਈਲ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਉਲੀਕਿਆ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਵੇਗਾ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫ਼ੋਨ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-pl/strings.xml b/packages/SystemUI/res-product/values-pl/strings.xml
new file mode 100644
index 0000000..9ba9b65
--- /dev/null
+++ b/packages/SystemUI/res-product/values-pl/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Brak karty SIM w tablecie."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Brak karty SIM w telefonie."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kody PIN nie pasują"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach tablet zostanie zresetowany, co spowoduje skasowanie wszystkich jego danych."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach telefon zostanie zresetowany, co spowoduje skasowanie wszystkich jego danych."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Tablet zostanie zresetowany, co spowoduje skasowanie wszystkich jego danych."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Telefon zostanie zresetowany, co spowoduje skasowanie wszystkich jego danych."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach użytkownik zostanie usunięty, co spowoduje skasowanie wszystkich danych użytkownika."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach użytkownik zostanie usunięty, co spowoduje skasowanie wszystkich danych użytkownika."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Urządzenie z Androidem TV za chwilę się wyłączy. Naciśnij przycisk, by pozostało włączone."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Urządzenie za chwilę się wyłączy. Naciśnij, by pozostało włączone."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Profil służbowy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Profil służbowy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-pt-rBR/strings.xml b/packages/SystemUI/res-product/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..73a0983
--- /dev/null
+++ b/packages/SystemUI/res-product/values-pt-rBR/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Não há um chip no tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Não há um chip no smartphone."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Os códigos PIN não coincidem"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este smartphone será redefinido, o que excluirá todos os dados dele."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este smartphone será redefinido, o que excluirá todos os dados dele."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este tablet será redefinido, o que excluirá todos os dados dele."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este smartphone será redefinido, o que excluirá todos os dados dele."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este usuário será removido, o que excluirá todos os dados do usuário."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este usuário será removido, o que excluirá todos os dados do usuário."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"O dispositivo Android TV entrará no modo de espera em breve. Pressione um botão para mantê-lo ativado."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"O dispositivo entrará no modo de espera em breve. Pressione para mantê-lo ativado."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-pt-rPT/strings.xml b/packages/SystemUI/res-product/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..e324686
--- /dev/null
+++ b/packages/SystemUI/res-product/values-pt-rPT/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nenhum cartão SIM no tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Nenhum cartão SIM no telemóvel."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Os códigos PIN não coincidem"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, este tablet será reposto, o que eliminará todos os dados do mesmo."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, este telemóvel será reposto, o que eliminará todos os dados do mesmo."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. Este tablet será reposto, o que eliminará todos os dados do mesmo."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes. Este telemóvel será reposto, o que eliminará todos os dados do mesmo."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, este utilizador será removido, o que eliminará todos os dados do mesmo."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, este utilizador será removido, o que eliminará todos os dados do mesmo."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"O dispositivo Android TV irá desligar-se brevemente. Prima um botão para o manter ligado."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"O dispositivo irá desligar-se brevemente. Prima para o manter ligado."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que eliminará todos os dados do mesmo."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que eliminará todos os dados do mesmo."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Desenhou o padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Desenhou o padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-pt/strings.xml b/packages/SystemUI/res-product/values-pt/strings.xml
new file mode 100644
index 0000000..73a0983
--- /dev/null
+++ b/packages/SystemUI/res-product/values-pt/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Não há um chip no tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Não há um chip no smartphone."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Os códigos PIN não coincidem"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este smartphone será redefinido, o que excluirá todos os dados dele."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este smartphone será redefinido, o que excluirá todos os dados dele."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este tablet será redefinido, o que excluirá todos os dados dele."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este smartphone será redefinido, o que excluirá todos os dados dele."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este usuário será removido, o que excluirá todos os dados do usuário."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, este usuário será removido, o que excluirá todos os dados do usuário."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"O dispositivo Android TV entrará no modo de espera em breve. Pressione um botão para mantê-lo ativado."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"O dispositivo entrará no modo de espera em breve. Pressione para mantê-lo ativado."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ro/strings.xml b/packages/SystemUI/res-product/values-ro/strings.xml
new file mode 100644
index 0000000..536d7d9
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ro/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nu există card SIM în tabletă."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Nu există card SIM în telefon."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Codurile PIN nu coincid"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Ați efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, această tabletă va fi resetată, iar toate datele acesteia vor fi șterse."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Ați efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, acest telefon va fi resetat, iar toate datele acestuia vor fi șterse."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Această tabletă va fi resetată, iar toate datele acesteia vor fi șterse."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Acest telefon va fi resetat, iar toate datele acestuia vor fi șterse."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Ați efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, acest utilizator va fi eliminat, iar toate datele utilizatorului vor fi șterse."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Ați efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, acest utilizator va fi eliminat, iar toate datele utilizatorului vor fi șterse."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Dispozitivul Android TV se va opri în curând. Apăsați un buton pentru a-l menține pornit."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Dispozitivul se va opri în curând. Apăsați pentru a-l menține pornit."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Profilul de serviciu va fi eliminat, iar toate datele profilului vor fi șterse."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Profilul de serviciu va fi eliminat, iar toate datele profilului vor fi șterse."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Ați desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, vi se va solicita să deblocați tableta cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> secunde."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Ați desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, vi se va solicita să deblocați telefonul cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> secunde."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ru/strings.xml b/packages/SystemUI/res-product/values-ru/strings.xml
new file mode 100644
index 0000000..a870774
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ru/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Нет SIM-карты."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Нет SIM-карты."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-коды не совпадают."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Вы пытались разблокировать планшет несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи произойдет сброс настроек и все данные на устройстве будут удалены."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Вы пытались разблокировать телефон несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи произойдет сброс настроек и все данные на устройстве будут удалены."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Достигнуто максимальное количество неудачных попыток разблокировать планшет (<xliff:g id="NUMBER">%d</xliff:g>). Настройки устройства будут сброшены, а все его данные – удалены."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Достигнуто максимальное количество неудачных попыток разблокировать телефон (<xliff:g id="NUMBER">%d</xliff:g>). Настройки устройства будут сброшены, а все его данные – удалены."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Вы пытались разблокировать планшет несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи профиль пользователя и все его данные будут удалены."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Вы пытались разблокировать телефон несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи профиль пользователя и все его данные будут удалены."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Устройство Android TV скоро выключится. Чтобы этого не произошло, нажмите любую кнопку."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Устройство скоро выключится. Чтобы этого не произошло, нажмите любую кнопку или коснитесь экрана."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Достигнуто максимальное количество неудачных попыток разблокировать планшет (<xliff:g id="NUMBER">%d</xliff:g>). Рабочий профиль и все его данные будут удалены."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Достигнуто максимальное количество неудачных попыток разблокировать телефон (<xliff:g id="NUMBER">%d</xliff:g>). Рабочий профиль и все его данные будут удалены."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Вы ввели неверный графический ключ несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи вам будет предложено разблокировать планшет с помощью аккаунта электронной почты.\n\nПовторите попытку через <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Вы ввели неверный графический ключ несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи вам будет предложено разблокировать телефон с помощью аккаунта электронной почты.\n\nПовторите попытку через <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-si/strings.xml b/packages/SystemUI/res-product/values-si/strings.xml
new file mode 100644
index 0000000..2d02d1f
--- /dev/null
+++ b/packages/SystemUI/res-product/values-si/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ටැබ්ලටයේ SIM පත නොමැත."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"දුරකථනය තුල SIM පතක් නැත."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN කේත නොගැළපේ."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"ඔබ ටැබ්ලට් පරිගණකය අගුළු හැරීමට <xliff:g id="NUMBER_0">%1$d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. තවත් අසාර්ථක උත්සාහයන් <xliff:g id="NUMBER_1">%2$d</xliff:g>කින් පසුව, මෙම ටැබ්ලට් පරිගණකය යළි සකසනු ඇති අතර, එය එහි සියලු දත්ත මකනු ඇත."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"ඔබ දුරකථනය අගුළු හැරීමට <xliff:g id="NUMBER_0">%1$d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. තවත් අසාර්ථක උත්සාහයන් <xliff:g id="NUMBER_1">%2$d</xliff:g>කින් පසුව, මෙම දුරකථනය යළි සකසනු ඇති අතර, එය එහි සියලු දත්ත මකනු ඇත."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"ඔබ ටැබ්ලට් පරිගණකය අගුළු හැරීමට <xliff:g id="NUMBER">%d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. මෙම ටැබ්ලට් පරිගණකය යළි සකසනු ඇති අතර, එය එහි සියලු පදත්ත මකනු ඇත."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"ඔබ දුරකථනය අගුළු හැරීමට <xliff:g id="NUMBER">%d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. මෙම දුරකථනය යළි සකසනු ඇති අතර, එය එහි සියලු පදත්ත මකනු ඇත."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"ඔබ ටැබ්ලට් පරිගණකය අගුළු හැරීමට <xliff:g id="NUMBER_0">%1$d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. තවත් අසාර්ථක උත්සාහයන් <xliff:g id="NUMBER_1">%2$d</xliff:g>කින් පසුව, මෙම පරිශීලකයා ඉවත් කරනු ඇති අතර, එය සියලු පරිශීලක දත්ත මකනු ඇත."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"ඔබ දුරකථනය අගුළු හැරීමට <xliff:g id="NUMBER_0">%1$d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. තවත් අසාර්ථක උත්සාහයන් <xliff:g id="NUMBER_1">%2$d</xliff:g>කින් පසුව, මෙම පරිශීලකයා ඉවත් කරනු ඇති අතර, එය සියලු පරිශීලක දත්ත මකනු ඇත."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV උපාංගය ඉක්මනින් ක්රියා විරහිත වනු ඇත; එය දිගටම ක්රියාත්මක කර තැබීමට බොත්තමක් ඔබන්න."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"උපාංගය ඉක්මනින් ක්රියා විරහිත වනු ඇත; එය දිගටම ක්රියාත්මක කර තැබීමට ඔබන්න."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"ඔබ ටැබ්ලට් පරිගණකය අගුළු හැරීමට <xliff:g id="NUMBER">%d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. කාර්යාල පැතිකඩ ඉවත් කරනු ඇති අතර, එය සියලු පැතිකඩ දත්ත මකනු ඇත."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"ඔබ දුරකථනය අගුළු හැරීමට <xliff:g id="NUMBER">%d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. කාර්යාල පැතිකඩ ඉවත් කරනු ඇති අතර, එය සියලු පැතිකඩ දත්ත මකනු ඇත."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"ඔබ අගුළු ඇරිමේ රටාව <xliff:g id="NUMBER_0">%1$d</xliff:g> වතාවක් වැරදියට ඇඳ ඇත. තවත් අසාර්ථක උත්සාහ <xliff:g id="NUMBER_1">%2$d</xliff:g> කින් පසුව, ඊ-තැපැල් ගිණුම භාවිතා කරමින් ඔබගේ ටැබ්ලටයේ අගුළු ඇරීමට ඔබට පවසනු ඇත.\n\n නැවත තත්පර <xliff:g id="NUMBER_2">%3$d</xliff:g> කින් උත්සාහ කරන්න."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%1$d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%2$d</xliff:g> න් පසුව, ඔබගේ ඊ-තැපැල් ලිපිනය භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%3$d</xliff:g> න් පසුව නැවත උත්සහ කරන්න."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-sk/strings.xml b/packages/SystemUI/res-product/values-sk/strings.xml
new file mode 100644
index 0000000..b57ecf9
--- /dev/null
+++ b/packages/SystemUI/res-product/values-sk/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"V tablete nie je žiadna SIM karta."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"V telefóne nie je žiadna SIM karta."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kódy PIN sa nezhodujú"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Tablet ste sa pokúsili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne odomknúť. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) bude tento tablet obnovený a všetky údaje, ktoré sú v ňom uložené, budú odstránené."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Telefón ste sa pokúsili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne odomknúť. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) bude tento telefón obnovený a všetky údaje, ktoré sú v ňom uložené, budú odstránené."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Tablet ste sa pokúsili <xliff:g id="NUMBER">%d</xliff:g>-krát nesprávne odomknúť. Tablet bude obnovený a všetky údaje, ktoré sú v ňom uložené, budú odstránené."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Telefón ste sa pokúsili <xliff:g id="NUMBER">%d</xliff:g>-krát nesprávne odomknúť. Telefón bude obnovený a všetky údaje, ktoré sú v ňom uložené, budú odstránené."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Tablet ste sa pokúsili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne odomknúť. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) bude tento používateľ odstránený a spolu s ním všetky jeho údaje."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Telefón ste sa pokúsili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne odomknúť. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) bude tento používateľ odstránený a spolu s ním všetky jeho údaje."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Zariadenie Android TV sa čoskoro vypne. Ak ho chcete ponechať zapnuté, stlačte ľubovoľné tlačidlo."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Zariadenie sa čoskoro vypne. Ak ho chcete ponechať zapnuté, stlačte ľubovoľné tlačidlo."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Tablet ste sa pokúsili <xliff:g id="NUMBER">%d</xliff:g>-krát nesprávne odomknúť. Pracovný profil bude odstránený spolu so všetkými údajmi."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Telefón ste sa pokúsili <xliff:g id="NUMBER">%d</xliff:g>-krát nesprávne odomknúť. Pracovný profil bude odstránený spolu so všetkými údajmi."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Už ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších <xliff:g id="NUMBER_1">%2$d</xliff:g> neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Už ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g>} s."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-sl/strings.xml b/packages/SystemUI/res-product/values-sl/strings.xml
new file mode 100644
index 0000000..99cb111
--- /dev/null
+++ b/packages/SystemUI/res-product/values-sl/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"V tabličnem računalniku ni kartice SIM."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"V telefonu ni kartice SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kodi PIN se ne ujemata"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Tablični računalnik ste neuspešno poskusili odkleniti <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. Če ga neuspešno poskusite odkleniti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, bo ponastavljen in vsi podatki v njem bodo izbrisani."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Telefon ste neuspešno poskusili odkleniti <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. Če ga neuspešno poskusite odkleniti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, bo ponastavljen in vsi podatki v njem bodo izbrisani."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Tablični računalnik ste neuspešno poskusili odkleniti <xliff:g id="NUMBER">%d</xliff:g>-krat, zato bo ponastavljen, vsi podatki v njem pa bodo izbrisani."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Telefon ste neuspešno poskusili odkleniti <xliff:g id="NUMBER">%d</xliff:g>-krat, zato bo ponastavljen, vsi podatki v njem pa bodo izbrisani."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Tablični računalnik ste neuspešno poskusili odkleniti <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. Če ga neuspešno poskusite odkleniti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, bo ta uporabnik odstranjen in vsi podatki uporabnika bodo izbrisani."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Telefon ste neuspešno poskusili odkleniti <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. Če ga neuspešno poskusite odkleniti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, bo ta uporabnik odstranjen in vsi podatki uporabnika bodo izbrisani."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Naprava Android TV se bo kmalu izklopila. Če tega ne želite, pritisnite poljuben gumb."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Naprava se bo kmalu izklopila. Če tega ne želite, pritisnite poljuben gumb."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Tablični računalnik ste neuspešno poskusili odkleniti <xliff:g id="NUMBER">%d</xliff:g>-krat. Delovni profil bo odstranjen in vsi podatki profila bodo izbrisani."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Telefon ste neuspešno poskusili odkleniti <xliff:g id="NUMBER">%d</xliff:g>-krat. Delovni profil bo odstranjen in vsi podatki profila bodo izbrisani."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno vnesli. Če ga neuspešno poskusite vnesti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, boste pozvani, da tablični računalnik odklenete z e-poštnim računom.\n\n Poskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno vnesli. Če ga neuspešno poskusite vnesti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, boste pozvani, da telefon odklenete z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-sq/strings.xml b/packages/SystemUI/res-product/values-sq/strings.xml
new file mode 100644
index 0000000..723c475
--- /dev/null
+++ b/packages/SystemUI/res-product/values-sq/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Nuk ka kartë SIM në tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Në telefon nuk ka kartë SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Kodet PIN nuk përputhen"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht për ta shkyçur tabletin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> përpjekjeve të tjera të pasuksesshme, tableti do të rivendoset, gjë që do të rivendosë të gjitha të dhënat e tij."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht për ta shkyçur telefonin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> përpjekjeve të tjera të pasuksesshme, telefoni do të rivendoset, gjë që do të fshijë të gjitha të dhënat e tij."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur tabletin. Ky tablet do të rivendoset, gjë që do të fshijë të gjitha të dhënat e tij."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur telefonin. Ky telefon do të rivendoset, gjë që do të fshijë të gjitha të dhënat e tij."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për ta shkyçur telefonin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, përdoruesi do të hiqet dhe të gjitha të dhënat e përdoruesit në të, do të fshihen."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për ta shkyçur telefonin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, përdoruesi do të hiqet dhe të gjitha të dhënat e përdoruesit në të, do të fshihen."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Pajisja Android TV do të fiket së shpejti. Shtyp një buton për ta mbajtur të ndezur."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Pajisja do të fiket së shpejti. Shtype për ta mbajtur të ndezur."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur tabletin. Profili i punës do të hiqet, gjë që do të fshijë të gjitha të dhënat e profilit."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur telefonin. Profili i punës do të hiqet, gjë që do të fshijë të gjitha të dhënat e profilit."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh tabletin duke përdorur një llogari mail-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh telefonin duke përdorur një llogari mail-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-sr/strings.xml b/packages/SystemUI/res-product/values-sr/strings.xml
new file mode 100644
index 0000000..0e6106e
--- /dev/null
+++ b/packages/SystemUI/res-product/values-sr/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"У таблету нема SIM картице."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"У телефону нема SIM картице."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN кодови се не подударају"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, овај таблет ће се ресетовати, чиме се бришу сви подаци корисника."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, овај телефон ће се ресетовати, чиме се бришу сви подаци корисника."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Овај таблет ће се ресетовати, чиме се бришу сви подаци."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Овај телефон ће се ресетовати, чиме се бришу сви подаци."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, уклонићемо овог корисника, чиме се бришу сви подаци корисника."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ће се ускоро искључити. Притисните дугме да би остао укључен."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Уређај ће се ускоро искључити. Притисните да би остао укључен."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Погрешно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо профил за Work, чиме се бришу сви подаци са профила."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо профил за Work, чиме се бришу сви подаци са профила."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, затражићемо да откључате таблет помоћу имејл налога.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, затражићемо да откључате телефон помоћу имејл налога.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-sv/strings.xml b/packages/SystemUI/res-product/values-sv/strings.xml
new file mode 100644
index 0000000..05de9eb
--- /dev/null
+++ b/packages/SystemUI/res-product/values-sv/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Inget SIM-kort i surfplattan."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Inget SIM-kort i mobilen."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Pinkoderna stämmer inte överens"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Du har försökt låsa upp surfplattan på ett felaktigt sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök återställs surfplattan och all data raderas."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Du har försökt låsa upp mobilen på ett felaktigt sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök återställs mobilen och all data raderas."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Du har försökt låsa upp surfplattan på ett felaktigt sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Surfplattan återställs och all data raderas."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Du har försökt låsa upp mobilen på ett felaktigt sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Mobilen återställs och all data raderas."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Du har försökt låsa upp surfplattan på ett felaktigt sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök tas användaren bort och all användardata raderas."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Du har försökt låsa upp mobilen på ett felaktigt sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök tas användaren bort och all användardata raderas."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV-enheten stängs snart av. Tryck på en knapp för att behålla den på."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Enheten stängs snart av. Tryck för att behålla den på."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Du har försökt låsa upp surfplattan på ett felaktigt sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Jobbprofilen tas bort och all profildata raderas."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Du har försökt låsa upp mobilen på ett felaktigt sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Jobbprofilen tas bort och all profildata raderas."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök måste du låsa upp surfplattan med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök måste du låsa upp mobilen med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-sw/strings.xml b/packages/SystemUI/res-product/values-sw/strings.xml
new file mode 100644
index 0000000..09eb0b2b
--- /dev/null
+++ b/packages/SystemUI/res-product/values-sw/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Hakuna SIM kadi katika kompyuta kibao."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Hakuna SIM kadi kwenye simu."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Nambari za PIN hazifanani"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Umejaribu kufungua kompyuta kibao mara <xliff:g id="NUMBER_0">%1$d</xliff:g> bila mafanikio. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, kompyuta hii kibao itarejeshwa katika hali iliyotoka nayo kiwandani, hatua itakayofuta data yake yote."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Umejaribu kufungua simu mara <xliff:g id="NUMBER_0">%1$d</xliff:g> bila mafanikio. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, simu hii itarejeshwa katika hali iliyotoka nayo kiwandani, hatua itakayofuta data yake yote."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Umejaribu kufungua simu mara <xliff:g id="NUMBER">%d</xliff:g> bila mafanikio. Kompyuta hii kibao itarejeshwa katika hali iliyotoka nayo kiwandani, hatua itakayofuta data yake yote."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Umejaribu kufungua simu mara <xliff:g id="NUMBER">%d</xliff:g> bila mafanikio. Simu hii itarejeshwa katika hali iliyotoka nayo kiwandani, hatua itakayofuta data yake yote."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Umejaribu kufungua kompyuta kibao mara <xliff:g id="NUMBER_0">%1$d</xliff:g> bila mafanikio. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, mtumiaji huyu ataondolewa, hatua itakayofuta data yake yote."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Umejaribu kufungua simu mara <xliff:g id="NUMBER_0">%1$d</xliff:g> bila mafanikio. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, mtumiaji huyu ataondolewa, hatua itakayofuta data yake yote."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Kifaa cha Android TV kitazima hivi karibuni; bonyeza kitufe ili kisizime."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Kifaa kitazima hivi karibuni; bonyeza ili kisizime."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Umejaribu kufungua kompyuta kibao mara <xliff:g id="NUMBER">%d</xliff:g> bila mafanikio. Wasifu wa kazini utaondolewa, hatua itakayofuta data yote ya wasifu."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Umejaribu kufungua simu mara <xliff:g id="NUMBER">%d</xliff:g> bila mafanikio. Wasifu wa kazini utaondolewa, hatua itakayofuta data yote ya wasifu."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, utaombwa kufungua kompyuta yako kibao kwa kutumia akaunti yako ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ta/strings.xml b/packages/SystemUI/res-product/values-ta/strings.xml
new file mode 100644
index 0000000..35e3f82
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ta/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"டேப்லெட்டில் சிம் கார்டு இல்லை."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"மொபைலில் சிம் கார்டு இல்லை."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"பின் குறியீடுகள் பொருந்தவில்லை"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"டேப்லெட்டைத் திறக்க, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக முயன்றால், இந்த டேப்லெட் மீட்டமைக்கப்பட்டு, அதன் எல்லாத் தரவும் நீக்கப்படும்."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"மொபைலைத் திறக்க, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக முயன்றால், இந்த மொபைல் மீட்டமைக்கப்பட்டு, அதன் எல்லாத் தரவும் நீக்கப்படும்."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"டேப்லெட்டைத் திறக்க, <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இந்த டேப்லெட் மீட்டமைக்கப்பட்டு, அதன் எல்லாத் தரவும் நீக்கப்படும்."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"மொபைலைத் திறக்க, <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இந்த மொபைல் மீட்டமைக்கப்பட்டு, அதன் எல்லாத் தரவும் நீக்கப்படும்."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"டேப்லெட்டைத் திறக்க, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக முயன்றால், இந்தப் பயனர் அகற்றப்பட்டு, எல்லாப் பயனர் தரவும் நீக்கப்படும்."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"மொபைலைத் திறக்க, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக முயன்றால், இந்தப் பயனர் அகற்றப்பட்டு, எல்லாப் பயனர் தரவும் நீக்கப்படும்."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV விரைவில் ஆஃப் ஆகலாம். இதைத் தொடர்ந்து ஆனில் வைக்க ஒரு பட்டனைத் தட்டவும்."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"இந்தச் சாதனம் விரைவில் ஆஃப் ஆகலாம், இதைத் தொடர்ந்து ஆனில் வைக்கத் தட்டவும்."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"டேப்லெட்டைத் திறக்க, <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். பணிக் கணக்கு அகற்றப்பட்டு, எல்லாச் சுயவிவரத் தரவும் நீக்கப்படும்."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"மொபைலைத் திறக்க, <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயன்றுவிட்டீர்கள். பணிக் கணக்கு அகற்றப்பட்டு, எல்லாச் சுயவிவரத் தரவும் நீக்கப்படும்."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"திறப்பதற்கான பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், மின்னஞ்சல் கணக்கைப் பயன்படுத்தி டேப்லெட்டைத் திறக்கும்படி கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"திறப்பதற்கான பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், மின்னஞ்சல் கணக்கைப் பயன்படுத்தி மொபைலைத் திறக்கும்படி கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-te/strings.xml b/packages/SystemUI/res-product/values-te/strings.xml
new file mode 100644
index 0000000..6f172ee
--- /dev/null
+++ b/packages/SystemUI/res-product/values-te/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"టాబ్లెట్లో SIM కార్డ్ లేదు."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ఫోన్లో SIM కార్డ్ లేదు."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"పిన్ కోడ్లు సరిపోలలేదు"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"మీరు టాబ్లెట్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఈ టాబ్లెట్ రీసెట్ చేయబడుతుంది, తద్వారా ఇందులోని మొత్తం డేటా తొలగించబడుతుంది."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"మీరు ఫోన్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఈ ఫోన్ రీసెట్ చేయబడుతుంది, తద్వారా ఇందులోని మొత్తం డేటా తొలగించబడుతుంది."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"మీరు టాబ్లెట్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER">%d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. ఈ టాబ్లెట్ రీసెట్ చేయబడుతుంది, తద్వారా ఇందులోని మొత్తం డేటా తొలగించబడుతుంది."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"మీరు ఫోన్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER">%d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. ఈ ఫోన్ రీసెట్ చేయబడుతుంది, తద్వారా ఇందులోని మొత్తం డేటా తొలగించబడుతుంది."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"మీరు టాబ్లెట్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఈ వినియోగదారు తీసివేయబడతారు, తద్వారా వినియోగదారు డేటా మొత్తం తొలగించబడుతుంది."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"మీరు ఫోన్ని అన్లాక్ చేయడానికి <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఈ వినియోగదారు తీసివేయబడతారు, తద్వారా వినియోగదారు డేటా మొత్తం తొలగించబడుతుంది."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV పరికరం త్వరలో ఆఫ్ అయిపోతుంది; దాన్ని ఆన్లో ఉంచడానికి బటన్ను నొక్కండి."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"పరికరం త్వరలో ఆఫ్ అయిపోతుంది; దీన్ని ఆన్లో ఉంచడానికి నొక్కండి."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"మీరు టాబ్లెట్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER">%d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. కార్యాలయ ప్రొఫైల్ తీసివేయబడుతుంది, తద్వారా ప్రొఫైల్ డేటా మొత్తం తొలగించబడుతుంది."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"మీరు ఫోన్ని అన్లాక్ చేయడానికి <xliff:g id="NUMBER">%d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేసారు. కార్యాలయ ప్రొఫైల్ తీసివేయబడుతుంది, తద్వారా ప్రొఫైల్ డేటా మొత్తం తొలగించబడుతుంది."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"మీరు మీ అన్లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, మీరు ఇమెయిల్ ఖాతాను ఉపయోగించి మీ టాబ్లెట్ను అన్లాక్ చేయాల్సి వస్తుంది.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"మీరు మీ అన్లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> విఫల ప్రయత్నాల తర్వాత, మీరు ఇమెయిల్ ఖాతాను ఉపయోగించి మీ ఫోన్ను అన్లాక్ చేయాల్సి వస్తుంది.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-th/strings.xml b/packages/SystemUI/res-product/values-th/strings.xml
new file mode 100644
index 0000000..8c9e72a
--- /dev/null
+++ b/packages/SystemUI/res-product/values-th/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ไม่มีซิมการ์ดในแท็บเล็ต"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"ไม่มีซิมการ์ดในโทรศัพท์"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"รหัส PIN ไม่ตรง"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"คุณปลดล็อกแท็บเล็ตไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะรีเซ็ตแท็บเล็ตเครื่องนี้ ซึ่งจะเป็นการลบข้อมูลทั้งหมดในเครื่อง"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"คุณปลดล็อกโทรศัพท์ไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะรีเซ็ตโทรศัพท์เครื่องนี้ ซึ่งจะเป็นการลบข้อมูลทั้งหมดในเครื่อง"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"คุณปลดล็อกแท็บเล็ตไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้ง ระบบจะรีเซ็ตแท็บเล็ตเครื่องนี้ ซึ่งจะเป็นการลบข้อมูลทั้งหมดในเครื่อง"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"คุณปลดล็อกโทรศัพท์ไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้ง ระบบจะรีเซ็ตโทรศัพท์เครื่องนี้ ซึ่งจะเป็นการลบข้อมูลทั้งหมดในเครื่อง"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"คุณปลดล็อกแท็บเล็ตไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะนำผู้ใช้รายนี้ออก ซึ่งจะเป็นการลบข้อมูลทั้งหมดของผู้ใช้"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"คุณปลดล็อกโทรศัพท์ไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะนำผู้ใช้รายนี้ออก ซึ่งจะเป็นการลบข้อมูลทั้งหมดของผู้ใช้"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"อุปกรณ์ Android TV จะปิดเครื่องในอีกไม่ช้า กดปุ่มเพื่อเปิดอุปกรณ์ต่อไป"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"อุปกรณ์จะปิดเครื่องในอีกไม่ช้า กดเพื่อเปิดอุปกรณ์ต่อไป"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"คุณปลดล็อกแท็บเล็ตไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้ง ระบบจะนำโปรไฟล์งานออก ซึ่งจะเป็นการลบข้อมูลโปรไฟล์ทั้งหมด"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"คุณปลดล็อกโทรศัพท์ไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้ง ระบบจะนำโปรไฟล์งานออก ซึ่งจะเป็นการลบข้อมูลโปรไฟล์ทั้งหมด"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล\n\n โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%3$d</xliff:g> วินาที"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้ง หากพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้บัญชีอีเมล\n\n โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%3$d</xliff:g> วินาที"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-tl/strings.xml b/packages/SystemUI/res-product/values-tl/strings.xml
new file mode 100644
index 0000000..d3901ee
--- /dev/null
+++ b/packages/SystemUI/res-product/values-tl/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Walang SIM card sa tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Walang SIM card sa telepono."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Hindi nagtutugma ang mga PIN code"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses mo nang sinubukang i-unlock ang tablet gamit ang maling password. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, ire-reset ang tablet na ito, na magiging dahilan upang ma-delete ang lahat ng data nito."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses mo nang sinubukang i-unlock ang telepono gamit ang maling password. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, ire-reset ang teleponong ito, na magiging dahilan upang ma-delete ang lahat ng data nito."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"<xliff:g id="NUMBER">%d</xliff:g> (na) beses mo nang sinubukang i-unlock ang tablet gamit ang maling password. Ire-reset ang tablet na ito, na magiging dahilan upang ma-delete ang lahat ng data nito."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"<xliff:g id="NUMBER">%d</xliff:g> (na) beses mo nang sinubukang i-unlock ang telepono gamit ang maling password. Ire-reset ang teleponong ito, na magiging dahilan upang ma-delete ang lahat ng data nito."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses mo nang sinubukang i-unlock ang tablet gamit ang maling password. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, aalisin ang user na ito, na magiging dahilan upang ma-delete ang lahat ng data ng user."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses mo nang sinubukang i-unlock ang telepono gamit ang maling password. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, aalisin ang user na ito, na magiging dahilan upang ma-delete ang lahat ng data ng user."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Mao-off na ang Android TV device; pumindot ng button para panatilihin itong naka-on."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Mao-off na ang device; pumindot para panatilihin itong naka-on."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"<xliff:g id="NUMBER">%d</xliff:g> (na) beses mo nang sinubukang i-unlock ang tablet gamit ang maling password. Aalisin ang profile sa trabaho, na magiging dahilan upang ma-delete ang lahat ng data sa profile."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"<xliff:g id="NUMBER">%d</xliff:g> (na) beses mo nang sinubukang i-unlock ang telepono gamit ang maling password. Aalisin ang profile sa trabaho, na magiging dahilan upang ma-delete ang lahat ng data sa profile."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-tr/strings.xml b/packages/SystemUI/res-product/values-tr/strings.xml
new file mode 100644
index 0000000..d6e0c39
--- /dev/null
+++ b/packages/SystemUI/res-product/values-tr/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Tablette SIM kart yok."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefonda SIM kart yok."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kodları eşleşmiyor"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Tabletin kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı bir şekilde açmayı denediniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız bu tablet sıfırlanacak ve tüm verileri silinecektir."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Telefonun kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı bir şekilde açmayı denediniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız bu telefon sıfırlanacak ve tüm verileri silinecektir."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Tabletin kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmayı denediniz. Bu tablet sıfırlanacak ve tüm verileri silinecektir."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Telefonun kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmayı denediniz. Bu telefon sıfırlanacak ve tüm verileri silinecektir."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Tabletin kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı bir şekilde açmayı denediniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız bu kullanıcı kaldırılacak ve tüm kullanıcı verileri silinecektir."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Telefonun kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı bir şekilde açmayı denediniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız bu kullanıcı kaldırılacak ve tüm kullanıcı verileri silinecektir."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV cihazı kısa süre içinde kapanacak. Cihazınızı açık tutmak için bir düğmeye basın."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Cihaz kısa süre içinde kapanacak. Cihazı açık tutmak için düğmeye basın."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Tabletin kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmayı denediniz. İş profili kaldırılacak ve tüm profil verileri silinecektir."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Telefonun kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmayı denediniz. İş profili kaldırılacak ve tüm profil verileri silinecektir."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> defa yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız denemeden sonra, tabletinizin kilidini bir e-posta hesabı kullanarak açmanız istenir.\n<xliff:g id="NUMBER_2">%3$d</xliff:g>\n saniye içinde tekrar deneyin."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız denemeden sonra telefonunuzun kilidini bir e-posta hesabı kullanarak açmanız istenir.\n<xliff:g id="NUMBER_2">%3$d</xliff:g>\n saniye içinde tekrar deneyin."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-uk/strings.xml b/packages/SystemUI/res-product/values-uk/strings.xml
new file mode 100644
index 0000000..a53043c
--- /dev/null
+++ b/packages/SystemUI/res-product/values-uk/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"У пристрої немає SIM-карти."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"У телефоні немає SIM-карти."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN-коди не збігаються"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Кількість невдалих спроб розблокувати планшет: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі буде скинуто налаштування планшета й видалено всі його дані."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі буде скинуто налаштування телефона й видалено всі його дані."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Кількість невдалих спроб розблокувати планшет: <xliff:g id="NUMBER">%d</xliff:g>. Буде скинуто налаштування цього планшета й видалено всі його дані."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER">%d</xliff:g>. Буде скинуто налаштування цього телефона й видалено всі його дані."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Кількість невдалих спроб розблокувати планшет: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі буде видалено цього користувача й усі його дані."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі буде видалено цього користувача й усі його дані."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Незабаром пристрій Android TV буде вимкнено. Натисніть кнопку, щоб цього не сталося."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Незабаром пристрій буде вимкнено. Натисніть, щоб цього не сталося."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Кількість невдалих спроб розблокувати планшет: <xliff:g id="NUMBER">%d</xliff:g>. Буде видалено робочий профіль і всі його дані."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER">%d</xliff:g>. Буде видалено робочий профіль і всі його дані."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі з’явиться запит розблокувати планшет за допомогою облікового запису електронної пошти.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі з’явиться запит розблокувати телефон за допомогою облікового запису електронної пошти.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-ur/strings.xml b/packages/SystemUI/res-product/values-ur/strings.xml
new file mode 100644
index 0000000..4569ee3
--- /dev/null
+++ b/packages/SystemUI/res-product/values-ur/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"ٹیبلیٹ میں کوئی SIM کارڈ نہیں ہے۔"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"فون میں کوئی SIM کارڈ نہيں ہے۔"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN کوڈز مماثل نہیں ہیں"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"آپ نے ٹیبلیٹ کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، اس ٹیبلیٹ کو دوبارہ ترتیب دے دیا جائے گا، جس سے اس کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"آپ نے فون کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، اس فون کو دوبارہ ترتیب دے دیا جائے گا، جس سے اس کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"آپ نے ٹیبلیٹ کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ اس ٹیبلیٹ کو دوبارہ ترتیب دے دیا جائے گا، جس سے اس کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"آپ نے فون کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ اس فون کو دوبارہ ترتیب دے دیا جائے گا، جس سے اس کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"آپ نے ٹیبلیٹ کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، اس صارف کو ہٹا دیا جائے گا، جس سے صارف کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"آپ نے فون کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، اس صارف کو ہٹا دیا جائے گا، جس سے صارف کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV آلہ جلد ہی بند ہوجائے گا آن رکھنے کے ليے بٹن دبائیں۔"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"آلہ جلد ہی بند ہوجائے گا اسے آن رکھنے کے ليے دبائیں۔"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"آپ نے ٹیبلیٹ کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ دفتری پروفائل ہٹا دیا جائے گا، جس سے پروفائل کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"آپ نے فون کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ دفتری پروفائل ہٹا دیا جائے گا، جس سے پروفائل کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کرکے اپنا ٹیبلیٹ غیر مقفل کرنے کو کہا جائے گا۔\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کرکے اپنا فون غیر مقفل کرنے کو کہا جائے گا۔\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-uz/strings.xml b/packages/SystemUI/res-product/values-uz/strings.xml
new file mode 100644
index 0000000..105ae9d
--- /dev/null
+++ b/packages/SystemUI/res-product/values-uz/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Planshetingizda SIM karta yo‘q."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Telefoningizda SIM karta yo‘q."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN kod mos kelmadi"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Siz planshetni qulfdan chiqarish uchun <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri urinish qildingiz. Agar yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinish qilsangiz, ushbu planshetda zavod sozlamalari qayta tiklanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Siz telefonni qulfdan chiqarish uchun <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri urinish qildingiz. Agar yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinish qilsangiz, ushbu telefonda zavod sozlamalari qayta tiklanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Siz planshetni qulfdan chiqarish uchun <xliff:g id="NUMBER">%d</xliff:g> marta noto‘g‘ri urinish qildingiz. Endi, ushbu planshetda zavod sozlamalari qayta tiklanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Siz telefonni qulfdan chiqarish uchun <xliff:g id="NUMBER">%d</xliff:g> marta noto‘g‘ri urinish qildingiz. Endi, ushbu telefonda zavod sozlamalari qayta tiklanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Siz planshetni qulfdan chiqarish uchun <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri urinish qildingiz. Agar yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinish qilsangiz, ushbu foydalanuvchi o‘chirib tashlanadi va undagi barcha foydalanuvchi ma’lumotlari ham o‘chib ketadi."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Siz telefonni qulfdan chiqarish uchun <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri urinish qildingiz. Agar yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinish qilsangiz, ushbu foydalanuvchi o‘chirib tashlanadi va undagi barcha foydalanuvchi ma’lumotlari ham o‘chib ketadi."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV qurilmasi oʻchish arafasida, yoniq qolishi uchun istalgan tugmani bosing."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Qurilma oʻchish arafasida, yoniq qolishi uchun istalgan tugmani bosing."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Siz planshetni qulfdan chiqarish uchun <xliff:g id="NUMBER">%d</xliff:g> marta noto‘g‘ri urinish qildingiz. Endi, ishchi profil o‘chirib tashlanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Siz telefonni qulfdan chiqarish uchun <xliff:g id="NUMBER">%d</xliff:g> marta noto‘g‘ri urinish qildingiz. Endi, ishchi profil o‘chirib tashlanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Grafik kalit <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato chizildi. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan keyin, sizdan e-pochtangizdan foydalanib, planshet qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan keyin yana urinib ko‘ring."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Grafik kalit <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato chizildi. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan keyin, sizdan e-pochtangizdan foydalanib, telefon qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan keyin qayta urinib ko‘ring."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-vi/strings.xml b/packages/SystemUI/res-product/values-vi/strings.xml
new file mode 100644
index 0000000..c9022ee
--- /dev/null
+++ b/packages/SystemUI/res-product/values-vi/strings.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Không có thẻ SIM nào trong máy tính bảng."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Không có thẻ SIM nào trong điện thoại."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Mã PIN không khớp"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Bạn đã mở khóa máy tính bảng sai <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, máy tính bảng này sẽ được đặt lại, tức là tất cả dữ liệu của máy tính bảng sẽ bị xóa."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Bạn đã mở khóa điện thoại sai <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, điện thoại này sẽ được đặt lại, tức là tất cả dữ liệu của điện thoại sẽ bị xóa."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Bạn đã mở khóa máy tính bảng sai <xliff:g id="NUMBER">%d</xliff:g> lần. Máy tính bảng này sẽ được đặt lại, tức là tất cả dữ liệu của máy tính bảng sẽ bị xóa."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Bạn đã mở khóa điện thoại sai <xliff:g id="NUMBER">%d</xliff:g> lần. Điện thoại này sẽ được đặt lại, tức là tất cả dữ liệu của điện thoại sẽ bị xóa."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Bạn đã mở khóa máy tính bảng sai <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, người dùng này sẽ bị xóa, tức là tất cả dữ liệu người dùng sẽ bị xóa."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Bạn đã mở khóa điện thoại sai <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, người dùng này sẽ bị xóa, tức là tất cả dữ liệu người dùng sẽ bị xóa."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for notification_bubble_title (8330481035191903164) -->
+ <skip/>
+ <!-- no translation found for notification_channel_summary_bubble (7235935211580860537) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Thiết bị Android TV sẽ sớm tắt. Hãy nhấn vào một nút để thiết bị vẫn bật."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Thiết bị sẽ sớm tắt. Hãy nhấn vào một nút để thiết bị vẫn bật."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Bạn đã mở khóa máy tính bảng sai <xliff:g id="NUMBER">%d</xliff:g> lần. Hồ sơ công việc sẽ bị xóa, tức là tất cả dữ liệu hồ sơ sẽ bị xóa."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Bạn đã mở khóa điện thoại sai <xliff:g id="NUMBER">%d</xliff:g> lần. Hồ sơ công việc sẽ bị xóa, tức là tất cả dữ liệu hồ sơ sẽ bị xóa."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Bạn đã vẽ không chính xác hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Bạn đã vẽ không chính xác hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-zh-rCN/strings.xml b/packages/SystemUI/res-product/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..7109c99
--- /dev/null
+++ b/packages/SystemUI/res-product/values-zh-rCN/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"平板电脑中没有 SIM 卡。"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"手机中没有 SIM 卡。"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN 码不匹配"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"您尝试解锁平板电脑后失败的次数已达 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,平板电脑将会被重置,而这将删除其中的所有数据。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"您尝试解锁手机后失败的次数已达 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,手机将会被重置,而这将删除其中的所有数据。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"您尝试解锁平板电脑后失败的次数已达 <xliff:g id="NUMBER">%d</xliff:g> 次。这部平板电脑将会被重置,而这将删除其中的所有数据。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"您尝试解锁手机后失败的次数已达 <xliff:g id="NUMBER">%d</xliff:g> 次。这部手机将会被重置,而这将删除其中的所有数据。"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"您尝试解锁平板电脑后失败的次数已达 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统将移除此用户,而这将删除所有的用户数据。"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"您尝试解锁手机后失败的次数已达 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统将移除此用户,而这将删除所有的用户数据。"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV 设备即将关闭;按一下相应的按钮即可让设备保持开启状态。"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"设备即将关闭;按一下即可让设备保持开启状态。"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"您尝试解锁平板电脑后失败的次数已达 <xliff:g id="NUMBER">%d</xliff:g> 次。系统将移除此工作资料,而这将删除所有的工作资料数据。"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"您尝试解锁手机后失败的次数已达 <xliff:g id="NUMBER">%d</xliff:g> 次。系统将移除此工作资料,而这将删除所有的工作资料数据。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒后重试。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒后重试。"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-zh-rHK/strings.xml b/packages/SystemUI/res-product/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..233b245
--- /dev/null
+++ b/packages/SystemUI/res-product/values-zh-rHK/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"平板電腦中沒有 SIM 卡。"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"手機中沒有 SIM 卡。"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN 碼不符"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將重設此平板電腦,而平板電腦的所有資料亦會一併刪除。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將重設此手機,而手機的所有資料亦會一併刪除。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將重設此平板電腦,而平板電腦的所有資料亦會一併刪除。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將重設此手機,而手機的所有資料亦會一併刪除。"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV 裝置即將關閉,按下按鈕即可保持開啟。"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"裝置即將關閉,輕按即可保持開啟。"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-zh-rTW/strings.xml b/packages/SystemUI/res-product/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..87e7dc4
--- /dev/null
+++ b/packages/SystemUI/res-product/values-zh-rTW/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"平板電腦中沒有 SIM 卡。"</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"手機中沒有 SIM 卡。"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"PIN 碼不符"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統會重設這台平板電腦,其中的所有資料也會一併遭到刪除。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統會重設這支手機,其中的所有資料也會一併遭到刪除。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統會重設這台平板電腦,其中的所有資料也會一併遭到刪除。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統會重設這支手機,其中的所有資料也會一併遭到刪除。"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,這位使用者將遭到移除,所有相關的使用者資料也會一併遭到刪除。"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,這位使用者將遭到移除,所有相關的使用者資料也會一併遭到刪除。"</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV 裝置即將進入待機模式。如要讓裝置保持開啟狀態,請按下任一按鈕。"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"裝置即將進入待機模式。如要讓裝置保持開啟狀態,請輕觸螢幕或按下按鈕。"</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。你的工作資料夾將遭到移除,所有設定檔資料也會一併遭到刪除。"</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。你的工作資料夾將遭到移除,所有設定檔資料也會一併遭到刪除。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"你的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統就會要求你透過電子郵件帳戶解鎖平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"你的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統就會要求你透過電子郵件帳戶解鎖手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values-zu/strings.xml b/packages/SystemUI/res-product/values-zu/strings.xml
new file mode 100644
index 0000000..2c8728b6
--- /dev/null
+++ b/packages/SystemUI/res-product/values-zu/strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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 global_action_screenshot (2760267567509131654) -->
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="3088787847082615459">"Alikho ikhadi le-SIM efonini."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="5124049236681993063">"Alikho ikhadi le-SIM efonini."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="1500814146841660886">"Iphinikhodi ayifani"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="2445671146665131857">"Uzame ngokungalungile ukuvula ithebulethi izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphezulu kwengu-<xliff:g id="NUMBER_1">%2$d</xliff:g> engaphumelelanga, le thebulethi izosethwa kabusha, okuzosusa yonke idatha yayo."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4738318327984389472">"Uzame ngokungalungile ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphezulu kwengu-<xliff:g id="NUMBER_1">%2$d</xliff:g> engaphumelelanga, le foni izosethwa kabusha, okuzosusa yonke idatha yayo."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="6974065787881197466">"Uzame ngokungalungile ukuvula ithebulethi izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Le thebulethi izosethwa kabusha, okuzosusa yonke idatha yayo."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4645797157486540692">"Uzame ngokungalungile ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Le foni izosethwa kabusha, okuzosusa yonke idatha yayo."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="2444432908572039632">"Uzame ngokungalungile ukuvula ithebulethi izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphezulu kwengu-<xliff:g id="NUMBER_1">%2$d</xliff:g> engaphumelelanga, lo msebenzisi uzosuswa, okuzosusa yonke idatha yomsebenzisi."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="3230300995829296824">"Uzame ngokungalungile ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphezulu kwengu-<xliff:g id="NUMBER_1">%2$d</xliff:g> engaphumelelanga, lo msebenzisi uzosuswa, okuzosusa yonke idatha yomsebenzisi."</string>
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (9046628517316763961) -->
+ <skip/>
+ <!-- no translation found for cancel (1089011503403416730) -->
+ <!-- no translation found for kg_failed_attempts_now_erasing_user (3588779327358321092) -->
+ <skip/>
+ <!-- no translation found for accessibility_casting (8708751252897282313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (6114158710353725041) -->
+ <skip/>
+ <!-- no translation found for accessibility_work_mode (1280025758672376313) -->
+ <!-- no translation found for kg_failed_attempts_almost_at_erase_profile (8345451368768804892) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_slow_charging (5148122851798085807) -->
+ <skip/>
+ <!-- no translation found for dock_alignment_not_charging (1002617659995575624) -->
+ <skip/>
+ <!-- no translation found for reset (8715144064608810383) -->
+ <skip/>
+ <!-- no translation found for notification_channel_alerts (3385787053375150046) -->
+ <skip/>
+ <!-- no translation found for app_info (5153758994129963243) -->
+ <skip/>
+ <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Idivayisi ye-Android TV maduze izovalwa, cindezela inkinobho ukuze uyigcine ivuliwe."</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Idivayisi maduze izovalwa, cindezela ukuze uyigcine ivuliwe."</string>
+<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="9063715142119087685">"Uzame ngokungalungile ukuvula ithebulethi izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Iphrofayela yomsebenzi izosuswa, okuzosusa yonke idatha yephrofayela."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="105463960684230996">"Uzame ngokungalungile ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Iphrofayela yomsebenzi izosuswa, okuzosusa yonke idatha yephrofayela."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="5123792377735688284">"Udwebe ngokungalungile iphethini yakho yokuvula ngezikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphumelelanga kaningi engu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, uzocelwa ukuthi uvule ithebulethi yakho usebenzisa i-akhawunti ye-imeyili.\n\nZama futhi kumasekhondi angu-<xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="3307854957632348753">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%1$d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%3$d</xliff:g> imizuzwana."</string>
+</resources>
diff --git a/packages/SystemUI/res-product/values/strings.xml b/packages/SystemUI/res-product/values/strings.xml
new file mode 100644
index 0000000..54e5d41
--- /dev/null
+++ b/packages/SystemUI/res-product/values/strings.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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">
+ <!-- Indication when device is slow charging due to misalignment on the dock. [CHAR LIMIT=60] -->
+ <string name="dock_alignment_slow_charging" product="default">Realign phone for faster charging</string>
+
+ <!-- Indication when device is not charging due to bad placement on the dock. [CHAR LIMIT=60] -->
+ <string name="dock_alignment_not_charging" product="default">Realign phone to charge wirelessly</string>
+
+ <!-- Message of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=NONE] -->
+ <string name="inattentive_sleep_warning_message" product="tv">The Android TV device will soon turn off; press a button to keep it on.</string>
+ <!-- Message of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=NONE] -->
+ <string name="inattentive_sleep_warning_message" product="default">The device will soon turn off; press to keep it on.</string>
+
+ <!-- Shown when there is no SIM card. -->
+ <string name="keyguard_missing_sim_message" product="tablet">No SIM card in tablet.</string>
+ <!-- Shown when there is no SIM card. -->
+ <string name="keyguard_missing_sim_message" product="default">No SIM card in phone.</string>
+
+ <!-- String shown in PUK screen when PIN codes don't match -->
+ <string name="kg_invalid_confirm_pin_hint" product="default">PIN codes does not match</string>
+
+ <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%1$d</xliff:g> times.
+ After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
+ this tablet will be reset, which will delete all its data.
+ </string>
+ <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_almost_at_wipe" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%1$d</xliff:g> times.
+ After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
+ this phone will be reset, which will delete all its data.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_now_wiping" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
+ This tablet will be reset, which will delete all its data.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_now_wiping" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
+ This phone will be reset, which will delete all its data.
+ </string>
+
+ <!-- Message shown when user is almost at the limit of password attempts where the user will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%1$d</xliff:g> times.
+ After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
+ this user will be removed, which will delete all user data.
+ </string>
+ <!-- Message shown when user is almost at the limit of password attempts where the user will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%1$d</xliff:g> times.
+ After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
+ this user will be removed, which will delete all user data.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the user will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
+ This user will be removed, which will delete all user data.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the user will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_now_erasing_user" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
+ This user will be removed, which will delete all user data.
+ </string>
+
+ <!-- Message shown when user is almost at the limit of password attempts where the profile will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%1$d</xliff:g> times.
+ After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
+ the work profile will be removed, which will delete all profile data.
+ </string>
+ <!-- Message shown when user is almost at the limit of password attempts where the profile will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%1$d</xliff:g> times.
+ After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
+ the work profile will be removed, which will delete all profile data.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the profile will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_now_erasing_profile" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
+ The work profile will be removed, which will delete all profile data.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the profile will be removed. [CHAR LIMIT=none] -->
+ <string name="kg_failed_attempts_now_erasing_profile" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
+ The work profile will be removed, which will delete all profile data.
+ </string>
+
+ <!-- Message shown in dialog when user is almost at the limit where they will be
+ locked out and may have to enter an alternate username/password to unlock the phone -->
+ <string name="kg_failed_attempts_almost_at_login" product="tablet">
+ You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
+ After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
+ you will be asked to unlock your tablet using an email account.\n\n
+ Try again in <xliff:g id="number">%3$d</xliff:g> seconds.
+ </string>
+ <!-- Message shown in dialog when user is almost at the limit where they will be
+ locked out and may have to enter an alternate username/password to unlock the phone -->
+ <string name="kg_failed_attempts_almost_at_login" product="default">
+ You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
+ After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
+ you will be asked to unlock your phone using an email account.\n\n
+ Try again in <xliff:g id="number">%3$d</xliff:g> seconds.
+ </string>
+
+</resources>
diff --git a/packages/SystemUI/res/layout/bubble_view.xml b/packages/SystemUI/res/layout/bubble_view.xml
index e2dea45..78f7cff 100644
--- a/packages/SystemUI/res/layout/bubble_view.xml
+++ b/packages/SystemUI/res/layout/bubble_view.xml
@@ -14,16 +14,8 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<com.android.systemui.bubbles.BubbleView
+<com.android.systemui.bubbles.BadgedImageView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:id="@+id/bubble_view">
-
- <com.android.systemui.bubbles.BadgedImageView
- android:id="@+id/bubble_image"
- android:layout_width="@dimen/individual_bubble_size"
- android:layout_height="@dimen/individual_bubble_size"
- android:clipToPadding="false"/>
-
-</com.android.systemui.bubbles.BubbleView>
+ android:id="@+id/bubble_view"
+ android:layout_width="@dimen/individual_bubble_size"
+ android:layout_height="@dimen/individual_bubble_size"/>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index ef2d061..8f64aab 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Die Android TV-toestel gaan binnekort afskakel; druk \'n knoppie om dit aan te hou."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Die toestel gaan binnekort afskakel; druk om dit aan te hou."</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index d39f399..d73c0ed 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"የስርዓት ዳሰሳ ተዘምኗል። ለውጦችን ለማድረግ ወደ ቅንብሮች ይሂዱ።"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"የስርዓት ዳሰሳን ለማዘመን ወደ ቅንብሮች ይሂዱ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ተጠባባቂ"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"የAndroid TV መሣሪያው በቅርቡ ይጠፋል፣ እንደበራ ለማቆየት ይጫኑ።"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"መሣሪያው በቅርቡ ይጠፋል፤ እንደበራ ለማቆየት ይጫኑ።"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 3fe4684..68fe91c 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -978,6 +978,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"تم تحديث التنقل داخل النظام. لإجراء التغييرات، يُرجى الانتقال إلى \"الإعدادات\"."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"الانتقال إلى \"الإعدادات\" لتعديل التنقل داخل النظام"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"وضع الاستعداد"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"سيتم إيقاف جهاز Android TV قريبًا، اضغط على أحد الأزرار لمواصلة تشغيله."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"سيتم إيقاف الجهاز قريبًا، اضغط لمواصلة تشغيله."</string>
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index c711b4d..b55f419 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -960,6 +960,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰা হ’ল। সলনি কৰিবলৈ ছেটিংসমূহ-লৈ যাওক।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰিবলৈ ছেটিংসমূহ-লৈ যাওক"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ষ্টেণ্ডবাই"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ডিভাইচটো অতি সোনকালে অফ হ\'ব, এইটো অন ৰাখিবলৈ যিকোনো এটা বুটাম টিপক।"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"এই ডিভাইচটো অতি সোনকালে অফ হ\'ব, এইটো অন ৰাখিবলৈ টিপক।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index c90b67c..95da981 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV cihazı tezliklə sönəcək; aktiv saxlamaq üçün düyməyə basın."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Cihaz tezliklə sönəcək; aktiv saxlamaq üçün basın."</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index f0f72b5..7b909cf 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -963,6 +963,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV će se uskoro isključiti. Pritisnite dugme da bi ostao uključen."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Uređaj će se uskoro isključiti. Pritisnite da bi ostao uključen."</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index ee82d76..412fcb7 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -970,6 +970,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацыя ў сістэме абноўлена. Каб унесці змяненні, перайдзіце ў Налады."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перайдзіце ў Налады, каб абнавіць параметры навігацыі ў сістэме"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Рэжым чакання"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Прылада Android TV неўзабаве выключыцца. Каб пакінуць яе ўключанай, націсніце кнопку."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Прылада неўзабаве выключыцца. Націсніце, каб пакінуць яе ўключанай."</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index b624dce..e9bf3c7 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Режимът за навигиране в системата е актуализиран. За да извършите промени, отворете настройките."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Отворете настройките, за да актуализирате режима за навигиране в системата"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим на готовност"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Устройството с Android TV скоро ще се изключи. Натиснете бутон, за да остане включено."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Устройството скоро ще се изключи. Натиснете, за да остане включено."</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 9dcdc59..60b23d7 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -960,6 +960,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"সিস্টেম নেভিগেশন আপডেট হয়েছে। পরিবর্তন করার জন্য সেটিংসে যান।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"সিস্টেম নেভিগেশন আপডেট করতে সেটিংসে যান"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"স্ট্যান্ডবাই"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ডিভাইস শীঘ্রই বন্ধ হয়ে যাবে, চালু রাখতে বোতাম প্রেস করুন।"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ডিভাইস শীঘ্রই বন্ধ হয়ে যাবে, চালু রাখতে প্রেস করুন।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 7774ed6..40f2d7c 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -965,6 +965,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV uređaj će se uskoro isključiti. Pritisnite dugme da ostane uključen."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Uređaj će se uskoro isključiti. Pritisnite da ostane uključen."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 589eeed..8e64a2e 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"El dispositiu Android TV s\'apagarà aviat; prem un botó per mantenir-lo encès."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"El dispositiu s\'apagarà aviat; prem per mantenir-lo encès."</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index dcefc84..2843bcd 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -968,6 +968,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Zařízení Android TV se brzy vypne, stisknutím tlačítka ho ponecháte zapnuté."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Zařízení se brzy vypne, stisknutím ho ponecháte zapnuté."</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index ba38784..da62c70 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV-enheden slukker snart. Tryk på en knap for at holde den tændt."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Enheden slukker snart. Tryk for at holde den tændt."</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 70b4f08..7e54703 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -962,6 +962,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Das Android TV-Gerät wird demnächst abgeschaltet. Drücke eine Taste, damit es eingeschaltet bleibt."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Das Gerät wird demnächst abgeschaltet. Drücke beispielsweise eine Taste oder berühre den Bildschirm, damit es eingeschaltet bleibt."</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 3c7105b..ab7f1e5 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Η πλοήγηση συστήματος ενημερώθηκε. Για να κάνετε αλλαγές, μεταβείτε στις Ρυθμίσεις."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Μεταβείτε στις Ρυθμίσεις για να ενημερώσετε την πλοήγηση συστήματος"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Κατάσταση αναμονής"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Η συσκευή Android TV σύντομα θα απενεργοποιηθεί. Πατήστε ένα κουμπί για να την κρατήσετε ενεργοποιημένη."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Η συσκευή σύντομα θα απενεργοποιηθεί. Πατήστε για να την κρατήσετε ενεργοποιημένη."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index e6a7d6c..35d4b4f 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"The Android TV device will soon turn off; press a button to keep it on."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"The device will soon turn off; press to keep it on."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 858de04..9ac53cd 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"The Android TV device will soon turn off; press a button to keep it on."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"The device will soon turn off; press to keep it on."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index e6a7d6c..35d4b4f 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"The Android TV device will soon turn off; press a button to keep it on."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"The device will soon turn off; press to keep it on."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index e6a7d6c..35d4b4f 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"The Android TV device will soon turn off; press a button to keep it on."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"The device will soon turn off; press to keep it on."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index a6abc8c..f7c937b 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -953,6 +953,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"The Android TV device will soon turn off; press a button to keep it on."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"The device will soon turn off; press to keep it on."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index db6ccb7..1787643 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Pronto se apagará el dispositivo Android TV; presiona un botón para mantenerlo encendido."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Pronto se apagará el dispositivo; presiona para mantenerlo encendido."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index ef52829..9a9f051 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"El dispositivo Android TV pronto se apagará; pulsa un botón para evitarlo."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"El dispositivo pronto se apagará si no interactúas con él."</string>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 57eed43..31bffa34 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV seade lülitub varsti välja; selle aktiivsena hoidmiseks vajutage nuppu."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Seade lülitub värsti välja; selle aktiivsena hoidmiseks vajutage nuppu."</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 9ffe463..fa24388 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV gailua laster itzaliko da; sakatu botoi bat piztuta mantentzeko."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Gailua laster itzaliko da; sakatu piztuta mantentzeko."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index ea56748..4ce5b27 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"پیمایش سیستم بهروزرسانی شد. برای انجام تغییرات به «تنظیمات» بروید."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"برای بهروزرسانی پیمایش سیستم، به «تنظیمات» بروید"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"آمادهبهکار"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"دستگاه Android TV بهزودی خاموش میشود، برای روشن نگهداشتن آن، دکمهای را فشار دهید."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"دستگاه بهزودی خاموش میشود، برای روشن نگهداشتن آن فشار دهید."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 32f2eec..8912db8 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ‑laite sammuu pian. Pidä se päällä painamalla painiketta."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Laite sammuu pian. Pidä se päällä painamalla jotakin."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index a144ddd..2bf724c 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"L\'appareil Android TV va bientôt s\'éteindre. Appuyez sur un bouton pour le laisser allumé."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"L\'appareil va bientôt s\'éteindre. Interagissez avec lui pour le laisser allumé."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index b126413..d2614de 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"L\'appareil Android TV va bientôt passer en mode Veille. Appuyez sur un bouton pour qu\'il reste allumé."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"L\'appareil va bientôt passer en mode Veille. Appuyez dessus pour qu\'il reste allumé."</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 88bfa05..a7a5726 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Pronto se apagará o dispositivo Android TV. Preme un botón para mantelo acendido."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Pronto se apagará o dispositivo. Tócao para mantelo acendido."</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 6f46b84..69c50e1 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -960,6 +960,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"સિસ્ટમ નૅવિગેશન અપડેટ કર્યું. ફેરફારો કરવા માટે, સેટિંગ પર જાઓ."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"સિસ્ટમ નૅવિગેશનને અપડેટ કરવા માટે સેટિંગ પર જાઓ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"સ્ટૅન્ડબાય"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android ટીવી ડિવાઇસ ટૂંક સમયમાં બંધ થશે; તેને ચાલુ રાખવા માટે બટન દબાવો."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ડિવાઇસ ટૂંક સમયમાં બંધ થશે; તેને ચાલુ રાખવા માટે દબાવો."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 1a5ce8e..3fc7870 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेविगेशन अपडेट हो गया. बदलाव करने के लिए \'सेटिंग\' पर जाएं."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेविगेशन अपडेट करने के लिए \'सेटिंग\' में जाएं"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टैंडबाई"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV डिवाइस जल्द ही बंद हो जाएगा. इसे चालू रखने के लिए किसी बटन को दबाएं."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"डिवाइस जल्द ही बंद हो जाएगा. इसे चालू रखने के लिए स्क्रीन पर टैप करें या किसी बटन को दबाएं."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index e270f0f..f19bdf5 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -963,6 +963,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Uređaj Android TV uskoro će se isključiti. Pritisnite gumb da bi ostao uključen."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Uređaj će se uskoro isključiti. Pritisnite da bi ostao uključen."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 5ff99c9..8624670 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Az Android TV eszköz hamarosan kikapcsol. Nyomja meg valamelyik gombot, hogy bekapcsolva tarthassa."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Az eszköz hamarosan kikapcsol. Nyomja meg, hogy bekapcsolva tarthassa."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index cf5ba2e..c02199e 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Համակարգի նավիգացիան թարմացվեց: Փոփոխություններ անելու համար անցեք կարգավորումներ:"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Թարմացրեք համակարգի նավիգացիան կարգավորումներում"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Սպասման ռեժիմ"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV սարքը շուտով կանջատվի: Սեղմեք որևէ կոճակ՝ միացրած թողնելու համար:"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Սարքը շուտով կանջատվի: Սեղմեք՝ միացրած թողնելու համար:"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index bb62498..99fa845 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Perangkat Android TV akan segera dinonaktifkan; tekan tombol untuk terus menyalakannya."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Perangkat akan segera dinonaktifkan, tekan untuk terus menyalakannya."</string>
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index d0deac3..cd23616 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV tækið slekkur á sér fljótlega. Ýttu á takka til að það slokkni ekki á því."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Tækið slekkur á sér fljótlega. Ýttu á takka til að það slokkni ekki á því."</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 6e370ac..9429c04 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"A breve il dispositivo Android TV si spegnerà. Premi un pulsante per tenerlo acceso."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"A breve il dispositivo si spegnerà. Premi per tenerlo acceso."</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index de0ebab..b2da88a 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -968,6 +968,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"הניווט במערכת עודכן. אפשר לערוך שינויים דרך ההגדרות."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"יש לעבור להגדרות כדי לעדכן את הניווט במערכת"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"המתנה"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"מכשיר Android TV ייכבה בקרוב. יש ללחוץ על לחצן כלשהו כדי שהוא ימשיך לפעול."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"המכשיר ייכבה בקרוב, יש ללחוץ כדי שהוא ימשיך לפעול."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 4703f5e..94dce86 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"システム ナビゲーションを更新しました。変更するには [設定] に移動してください。"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"システム ナビゲーションを更新するには [設定] に移動してください"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"スタンバイ"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV デバイスはまもなく OFF になります。ON 状態を維持するには、ボタンを押してください。"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"このデバイスはまもなく OFF になります。ON 状態を維持するには、ボタンを押してください。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 30c34ba..d1e37a4 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"სისტემური ნავიგაცია განახლდა. ცვლილებების შესატანად გადადით პარამეტრებზე."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"სისტემური ნავიგაციის გასაახლებლად გადადით პარამეტრებზე"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"მოლოდინის რეჟიმი"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV მოწყობილობა მალე გამოირთვება, დააჭირეთ ღილაკს, რომ ჩართული დარჩეს."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"მოწყობილობა მალე გამოირთვება, დააჭირეთ, რომ ჩართული დარჩეს."</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index cb4b393..c77a075 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Жүйе навигациясы жаңартылды. Өзгерту енгізу үшін \"Параметрлер\" бөліміне өтіңіз."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Жүйе навигациясын жаңарту үшін \"Параметрлер\" бөліміне өтіңіз."</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Күту режимі"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV құрылғысы жақын арада өшеді. Оны қосулы қалдыру үшін басыңыз."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Құрылғы жақын арада өшеді. Оны қосулы қалдыру үшін басыңыз."</string>
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 0d9337b..0cb6910 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"បានធ្វើបច្ចុប្បន្នភាពការរុករកក្នុងប្រព័ន្ធ។ ដើម្បីធ្វើការផ្លាស់ប្ដូរ សូមចូលទៅកាន់ការកំណត់។"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ចូលទៅកាន់ការកំណត់ ដើម្បីធ្វើបច្ចុប្បន្នភាពការរុករកក្នុងប្រព័ន្ធ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ផ្អាកដំណើរការ"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"ឧបករណ៍ Android TV នឹងបិទក្នុងពេលឆាប់ៗនេះ សូមចុចប៊ូតុងដើម្បីបន្តបើកឧបករណ៍។"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ឧបករណ៍នឹងបិទក្នុងពេលឆាប់ៗនេះ សូមចុចដើម្បីបន្តបើកឧបករណ៍។"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 3fbe942..c736240 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಲು, ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಹೋಗಿ."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ್ ಅಪ್ಡೇಟ್ ಮಾಡಲು ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಹೋಗಿ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ಸ್ಟ್ಯಾಂಡ್ಬೈ"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"ಈ Android TV ಸಾಧನವು ಶೀಘ್ರವೇ ಆಫ್ ಆಗುತ್ತದೆ; ಇದನ್ನು ಆನ್ನಲ್ಲಿಡಲು ಬಟನ್ ಅನ್ನು ಒತ್ತಿರಿ."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ಈ ಸಾಧನವು ಶೀಘ್ರವೇ ಆಫ್ ಆಗುತ್ತದೆ; ಇದನ್ನು ಆನ್ನಲ್ಲಿಡಲು ಒತ್ತಿರಿ."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 7923c6f..a60f736 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"시스템 탐색이 업데이트되었습니다. 변경하려면 설정으로 이동하세요."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"설정으로 이동하여 시스템 탐색을 업데이트하세요."</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"대기"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV가 곧 꺼집니다. 계속 켜 두려면 버튼을 누르세요."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"기기가 곧 꺼집니다. 계속 켜 두려면 누르세요."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index ba029f1..80aa6a1 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Тутум чабыттоосу жаңыртылды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Тутум чабыттоосун жаңыртуу үчүн Жөндөөлөргө өтүңүз"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Көшүү режими"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV түзмөгү жакында өчүрүлөт, аны күйүк боюнча калтыруу үчүн баскычты басыңыз."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Түзмөк жакында өчүрүлөт, күйүк боюнча калтыруу үчүн басып коюңуз."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 4376cc5..8b3be64 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ອັບເດດການນຳທາງລະບົບແລ້ວ. ເພື່ອປ່ຽນແປງ, ກະລຸນາໄປທີ່ການຕັ້ງຄ່າ."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ໄປທີ່ການຕັ້ງຄ່າເພື່ອອັບເດດການນຳທາງລະບົບ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ສະແຕນບາຍ"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"ອຸປະກອນ Android TV ຈະປິດໃນອີກບໍ່ດົນ, ກົດປຸ່ມໃດໜຶ່ງເພື່ອເປີດມັນໄວ້ຕໍ່."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ອຸປະກອນຈະປິດໃນອີກບໍ່ດົນ, ກົດເພື່ອເປີດມັນໄວ້ຕໍ່."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 2534a3b..c7282cd 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -968,6 +968,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"„Android TV“ įrenginys netrukus išsijungs. Paspauskite mygtuką, kad jis liktų įjungtas."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Įrenginys netrukus išsijungs. Paspauskite, kad jis liktų įjungtas."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 9604dc2..e99462b 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -963,6 +963,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ierīce drīz izslēgsies. Nospiediet pogu, lai tā paliktu ieslēgta."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Ierīce drīz izslēgsies. Nospiediet, lai tā paliktu ieslēgta."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index f9c5c4a..a607f75 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигацијата на системот е ажурирана. За да извршите промени, одете во „Поставки“."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Одете во „Поставки“ за да ја ажурирате навигацијата на системот"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Подготвеност"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Уредот со Android TV наскоро ќе се исклучи, притиснете копче за да остане вклучен."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Уредот наскоро ќе се исклучи, притиснете за да остане вклучен."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index fd3f16c..53ce5ab 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -960,6 +960,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"സിസ്റ്റം നാവിഗേഷൻ അപ്ഡേറ്റ് ചെയ്തു. മാറ്റങ്ങൾ വരുത്താൻ ക്രമീകരണത്തിലേക്ക് പോവുക."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"സിസ്റ്റം നാവിഗേഷൻ അപ്ഡേറ്റ് ചെയ്യാൻ ക്രമീകരണത്തിലേക്ക് പോവുക"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"സ്റ്റാൻഡ്ബൈ"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android ടിവി ഉടൻ ഓഫാകും, ഓണാക്കി നിർത്താൻ ഒരു ബട്ടൺ അമർത്തുക."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ഉപകരണം ഉടൻ ഓഫാകും, ഓണാക്കി നിർത്താൻ അമർത്തുക."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 0939c72..75af9cd 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Системийн навигацыг шинэчиллээ. Өөрчлөхийн тулд Тохиргоо руу очно уу."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Системийн навигацыг шинэчлэхийн тулд Тохиргоо руу очно уу"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Зогсолтын горим"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Андройд ТВ төхөөрөмж удахгүй унтрах тул асаалттай хэвээр байлгахын тулд товчлуур дээр дарна уу."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Төхөөрөмж удахгүй унтрах тул асаалттай хэвээр байлгахын тулд дарна уу."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 5326e37..089df33 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"सिस्टम नेव्हिगेशन अपडेट केले. बदल करण्यासाठी, सेटिंग्जवर जा."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"सिस्टम नेव्हिगेशन अपडेट करण्यासाठी सेटिंग्जवर जा"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टँडबाय"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV डिव्हाइस लवकरच बंद होणार आहे; सुरू ठेवण्यासाठी बटण दाबा."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"डिव्हाइस लवकरच बंद होणार आहे; सुरू ठेवण्यासाठी स्क्रीनवर किंवा बटण दाबा."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 25d73c0..3073c9f 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Peranti Android TV akan mati tidak lama lagi; tekan butang untuk memastikan peranti terus hidup."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Peranti akan mati tidak lama lagi; tekan untuk memastikan peranti terus hidup."</string>
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index beca4c4..9fcb86e 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ပြီးပါပြီ။ အပြောင်းအလဲများ ပြုလုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ။"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"အသင့်အနေအထား"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV စက်သည် မကြာမီ ပိတ်သွားပါမည်၊ ဆက်ဖွင့်ထားရန် ခလုတ်တစ်ခုနှိပ်ပါ။"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"စက်သည် မကြာမီ ပိတ်သွားပါမည်၊ ဆက်ဖွင့်ထားပါ။"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index a07451d..9a9854b 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV-enheten slås snart av. Trykk på en knapp for å holde den på."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Enheten slås snart av. Trykk for å holde den på."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 39e612a..fa1fa56 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"प्रणालीको नेभिगेसन अद्यावधिक गरियो। परिवर्तन गर्न सेटिङमा जानुहोस्।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"प्रणालीको नेभिगेसन अद्यावधिक गर्न सेटिङमा जानुहोस्"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्ट्यान्डबाई"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV यन्त्र चाँडै निष्क्रिय हुने छ; सक्रिय राख्न कुनै बटन थिच्नुहोस्।"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"यो यन्त्र चाँडै निष्क्रिय हुने छ; सक्रिय राख्न थिच्नुहोस्।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index a1b7c29..9aa9f1e 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Het Android TV-apparaat wordt binnenkort uitgeschakeld. Druk op een knop om het ingeschakeld te houden."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Het apparaat wordt binnenkort uitgeschakeld. Druk om het ingeschakeld te houden."</string>
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 5a9d136..4d467fe 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -960,6 +960,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍ଡେଟ୍ ହୋଇଛି। ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ, ସେଟିଂସ୍କୁ ଯାଆନ୍ତୁ।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍ଡେଟ୍ କରିବା ପାଇଁ ସେଟିଂସ୍କୁ ଯାଆନ୍ତୁ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ଷ୍ଟାଣ୍ଡବାଏ"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android ଟିଭି ଡିଭାଇସ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯିବ; ଏହା ଚାଲୁ ରଖିବା ପାଇଁ ଏକ ବଟନ୍ ଦବାନ୍ତୁ।"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ଡିଭାଇସ୍ ଶୀଘ୍ର ବନ୍ଦ ହୋଇଯିବ; ଚାଲୁ ରଖିବା ପାଇଁ ଦବାନ୍ତୁ।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 84052d7..cce1df3 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -960,6 +960,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਤਬਦੀਲੀਆਂ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ਸਟੈਂਡਬਾਈ"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ਡੀਵਾਈਸ ਜਲਦ ਹੀ ਬੰਦ ਹੋ ਜਾਵੇਗਾ; ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣ ਲਈ ਕੋਈ ਬਟਨ ਦਬਾਓ।"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"ਡੀਵਾਈਸ ਜਲਦ ਹੀ ਬੰਦ ਹੋ ਜਾਵੇਗਾ, ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 4e7b0de..0a9c174 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -968,6 +968,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Urządzenie z Androidem TV za chwilę się wyłączy. Naciśnij przycisk, by pozostało włączone."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Urządzenie za chwilę się wyłączy. Naciśnij, by pozostało włączone."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 79dff12..9459e81 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"O dispositivo Android TV entrará no modo de espera em breve. Pressione um botão para mantê-lo ativado."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"O dispositivo entrará no modo de espera em breve. Pressione para mantê-lo ativado."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index ab1fc96..b235bda 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"O dispositivo Android TV irá desligar-se brevemente. Prima um botão para o manter ligado."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"O dispositivo irá desligar-se brevemente. Prima para o manter ligado."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 79dff12..9459e81 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"O dispositivo Android TV entrará no modo de espera em breve. Pressione um botão para mantê-lo ativado."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"O dispositivo entrará no modo de espera em breve. Pressione para mantê-lo ativado."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index c2803aa..ea82ec3 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -963,6 +963,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Dispozitivul Android TV se va opri în curând. Apăsați un buton pentru a-l menține pornit."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Dispozitivul se va opri în curând. Apăsați pentru a-l menține pornit."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 9d0b2a9..fddb735 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -968,6 +968,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Параметры навигации в системе обновлены. Чтобы изменить их, перейдите в настройки."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Чтобы обновить параметры навигации в системе, перейдите в настройки."</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Переход в режим ожидания"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Устройство Android TV скоро выключится. Чтобы этого не произошло, нажмите любую кнопку."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Устройство скоро выключится. Чтобы этого не произошло, нажмите любую кнопку или коснитесь экрана."</string>
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 1b4db04..c28b189 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"පද්ධති සංචලනය යාවත්කාලීන කළා. වෙනස්කම් සිදු කිරීමට, සැකසීම් වෙත යන්න."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"පද්ධති සංචලනය යාවත්කාලීන කිරීමට සැකසීම් වෙත යන්න"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"පොරොත්තු"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV උපාංගය ඉක්මනින් ක්රියා විරහිත වනු ඇත; එය දිගටම ක්රියාත්මක කර තැබීමට බොත්තමක් ඔබන්න."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"උපාංගය ඉක්මනින් ක්රියා විරහිත වනු ඇත; එය දිගටම ක්රියාත්මක කර තැබීමට ඔබන්න."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 9cf97c9..ca929a0 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -968,6 +968,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Zariadenie Android TV sa čoskoro vypne. Ak ho chcete ponechať zapnuté, stlačte ľubovoľné tlačidlo."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Zariadenie sa čoskoro vypne. Ak ho chcete ponechať zapnuté, stlačte ľubovoľné tlačidlo."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 690e297..5b65bbc 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -968,6 +968,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Naprava Android TV se bo kmalu izklopila. Če tega ne želite, pritisnite poljuben gumb."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Naprava se bo kmalu izklopila. Če tega ne želite, pritisnite poljuben gumb."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 4ef95c5..b1be1fd 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Pajisja Android TV do të fiket së shpejti. Shtyp një buton për ta mbajtur të ndezur."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Pajisja do të fiket së shpejti. Shtype për ta mbajtur të ndezur."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 19bcca8..26c6220 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -963,6 +963,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигација система је ажурирана. Да бисте унели измене, идите у Подешавања."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Идите у Подешавања да бисте ажурирали навигацију система"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Стање приправности"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV ће се ускоро искључити. Притисните дугме да би остао укључен."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Уређај ће се ускоро искључити. Притисните да би остао укључен."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 1177000..4f32f03 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV-enheten stängs snart av. Tryck på en knapp för att behålla den på."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Enheten stängs snart av. Tryck för att behålla den på."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index bf85374..921bdd9 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Umesasisha usogezaji kwenye mfumo. Ili ufanye mabadiliko, 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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Kifaa cha Android TV kitazima hivi karibuni; bonyeza kitufe ili kisizime."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Kifaa kitazima hivi karibuni; bonyeza ili kisizime."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 0990b7f..5ca715b 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"சிஸ்டம் நேவிகேஷன் மாற்றப்பட்டது. மாற்றங்களைச் செய்ய ‘அமைப்புகளுக்குச்’ செல்லவும்."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"சிஸ்டம் நேவிகேஷனை மாற்ற ’அமைப்புகளுக்குச்’ செல்லவும்"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"இயக்க நேரம்"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV விரைவில் ஆஃப் ஆகலாம். இதைத் தொடர்ந்து ஆனில் வைக்க ஒரு பட்டனைத் தட்டவும்."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"இந்தச் சாதனம் விரைவில் ஆஃப் ஆகலாம், இதைத் தொடர்ந்து ஆனில் வைக்கத் தட்டவும்."</string>
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 21e915c..07fef971 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"సిస్టమ్ నావిగేషన్ అప్డేట్ చేయబడింది. మార్పులు చేయడానికి, సెట్టింగ్లకు వెళ్లండి."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"సిస్టమ్ నావిగేషన్ను అప్డేట్ చేయడానికి సెట్టింగ్లకు వెళ్లండి"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"స్టాండ్బై"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV పరికరం త్వరలో ఆఫ్ అయిపోతుంది; దాన్ని ఆన్లో ఉంచడానికి బటన్ను నొక్కండి."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"పరికరం త్వరలో ఆఫ్ అయిపోతుంది; దీన్ని ఆన్లో ఉంచడానికి నొక్కండి."</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 45cfe92..14b7d74 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"อัปเดตการไปยังส่วนต่างๆ ของระบบแล้ว หากต้องการเปลี่ยนแปลง ให้ไปที่การตั้งค่า"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"ไปที่การตั้งค่าเพื่ออัปเดตการไปยังส่วนต่างๆ ของระบบ"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"สแตนด์บาย"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"อุปกรณ์ Android TV จะปิดเครื่องในอีกไม่ช้า กดปุ่มเพื่อเปิดอุปกรณ์ต่อไป"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"อุปกรณ์จะปิดเครื่องในอีกไม่ช้า กดเพื่อเปิดอุปกรณ์ต่อไป"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index bb150fc..3821262 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Mao-off na ang Android TV device; pumindot ng button para panatilihin itong naka-on."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Mao-off na ang device; pumindot para panatilihin itong naka-on."</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 5a0ede0..3dddbf5 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV cihazı kısa süre içinde kapanacak. Cihazınızı açık tutmak için bir düğmeye basın."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Cihaz kısa süre içinde kapanacak. Cihazı açık tutmak için düğmeye basın."</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index eddc403..a3e9e62 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -968,6 +968,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навігацію в системі оновлено. Щоб внести зміни, перейдіть у налаштування."</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перейдіть у налаштування, щоб оновити навігацію в системі"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим очікування"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Незабаром пристрій Android TV буде вимкнено. Натисніть кнопку, щоб цього не сталося."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Незабаром пристрій буде вимкнено. Натисніть, щоб цього не сталося."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 3962d4f..e30b9ae 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"سسٹم نیویگیشن اپ ڈیٹ کیا گیا۔ تبدیلیاں کرنے کے لیے، ترتیبات پر جائیں۔"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"سسٹم نیویگیشن اپ ڈیٹ کرنے کے لیے ترتیبات پر جائیں"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"اسٹینڈ بائی"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV آلہ جلد ہی بند ہوجائے گا آن رکھنے کے ليے بٹن دبائیں۔"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"آلہ جلد ہی بند ہوجائے گا اسے آن رکھنے کے ليے دبائیں۔"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 2f84839..ec8639b 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV qurilmasi oʻchish arafasida, yoniq qolishi uchun istalgan tugmani bosing."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Qurilma oʻchish arafasida, yoniq qolishi uchun istalgan tugmani bosing."</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index f966c2e..9291563 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -960,6 +960,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Thiết bị Android TV sẽ sớm tắt. Hãy nhấn vào một nút để thiết bị vẫn bật."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Thiết bị sẽ sớm tắt. Hãy nhấn vào một nút để thiết bị vẫn bật."</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 64cf56e..55db2b5 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系统导航已更新。要进行更改,请转到“设置”。"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"转到“设置”即可更新系统导航"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待机"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV 设备即将关闭;按一下相应的按钮即可让设备保持开启状态。"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"设备即将关闭;按一下即可让设备保持开启状态。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index a49bc64..8a28aef 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統導覽已更新。如需變更,請前往「設定」。"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"前往「設定」更新系統導覽"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV 裝置即將關閉,按下按鈕即可保持開啟。"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"裝置即將關閉,輕按即可保持開啟。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 2f468d0..79f336d 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -958,6 +958,4 @@
<string name="notification_content_system_nav_changed" msgid="5077913144844684544">"系統操作機制已更新。如要進行變更,請前往「設定」。"</string>
<string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"請前往「設定」更新系統操作機制"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Android TV 裝置即將進入待機模式。如要讓裝置保持開啟狀態,請按下任一按鈕。"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"裝置即將進入待機模式。如要讓裝置保持開啟狀態,請輕觸螢幕或按下按鈕。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 2ee89db..bc3fcc0 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -958,6 +958,4 @@
<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>
- <string name="inattentive_sleep_warning_message" product="tv" msgid="6017523991455860482">"Idivayisi ye-Android TV maduze izovalwa, cindezela inkinobho ukuze uyigcine ivuliwe."</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="4866963937818527643">"Idivayisi maduze izovalwa, cindezela ukuze uyigcine ivuliwe."</string>
</resources>
diff --git a/packages/SystemUI/res/values/arrays_tv.xml b/packages/SystemUI/res/values/arrays_tv.xml
index 1fe6141..95716c8 100644
--- a/packages/SystemUI/res/values/arrays_tv.xml
+++ b/packages/SystemUI/res/values/arrays_tv.xml
@@ -36,5 +36,6 @@
<string-array name="audio_recording_disclosure_exempt_apps" translatable="false">
<item>com.google.android.katniss</item>
+ <item>com.google.android.apps.mediashell</item>
</string-array>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1dd5496..1053750 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -990,12 +990,6 @@
<!-- Message shown when face authentication fails and the pin pad is visible. [CHAR LIMIT=60] -->
<string name="keyguard_retry">Swipe up to try again</string>
- <!-- Indication when device is slow charging due to misalignment on the dock. [CHAR LIMIT=60] -->
- <string name="dock_alignment_slow_charging" product="default">Realign phone for faster charging</string>
-
- <!-- Indication when device is not charging due to bad placement on the dock. [CHAR LIMIT=60] -->
- <string name="dock_alignment_not_charging" product="default">Realign phone to charge wirelessly</string>
-
<!-- Text on keyguard screen and in Quick Settings footer indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=60] -->
<string name="do_disclosure_generic">This device is managed by your organization</string>
@@ -2498,9 +2492,4 @@
<!-- Title of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=25] -->
<string name="inattentive_sleep_warning_title">Standby</string>
- <!-- Message of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=NONE] -->
- <string name="inattentive_sleep_warning_message" product="tv">The Android TV device will soon turn off; press a button to keep it on.</string>
- <!-- Message of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=NONE] -->
- <string name="inattentive_sleep_warning_message" product="default">The device will soon turn off; press to keep it on.</string>
-
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
index 493186b..41dd5bbf 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
@@ -139,6 +139,8 @@
}
}
+ // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
+ // ForegroundCoordinator
// Update appOp if there's an associated pending or visible notification:
final String foregroundKey = getStandardLayoutKey(userId, packageName);
if (foregroundKey != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
index c4e2762..8105faa 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
@@ -52,6 +52,9 @@
NotifCollection notifCollection) {
mContext = context;
mForegroundServiceController = foregroundServiceController;
+
+ // TODO: (b/145659174) remove mEntryManager when moving to NewNotifPipeline. Replaced by
+ // ForegroundCoordinator
mEntryManager = notificationEntryManager;
mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@Override
@@ -171,8 +174,8 @@
true /* create if not found */);
}
- // TODO: remove this when fully migrated to the NewNotifPipeline (work done in
- // ForegroundCoordinator)
+ // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
+ // ForegroundCoordinator
private void tagForeground(NotificationEntry entry) {
final StatusBarNotification sbn = entry.getSbn();
ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps(
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleService.kt b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleService.kt
new file mode 100644
index 0000000..9ceafc6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleService.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.assist
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+import dagger.Lazy
+import javax.inject.Inject
+
+class AssistHandleService @Inject constructor(private val assistManager: Lazy<AssistManager>)
+ : Service() {
+
+ private val binder = object : IAssistHandleService.Stub() {
+ override fun requestAssistHandles() {
+ assistManager.get().requestAssistHandles()
+ }
+ }
+
+ override fun onBind(intent: Intent?): IBinder? {
+ return binder
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java b/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java
index 6f5a17d..96939b01 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java
@@ -16,6 +16,7 @@
package com.android.systemui.assist;
+import android.app.Service;
import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
@@ -33,8 +34,11 @@
import javax.inject.Named;
import javax.inject.Singleton;
+import dagger.Binds;
import dagger.Module;
import dagger.Provides;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
/** Module for dagger injections related to the Assistant. */
@Module
@@ -87,4 +91,9 @@
static Clock provideSystemClock() {
return SystemClock::uptimeMillis;
}
+
+ @Binds
+ @IntoMap
+ @ClassKey(AssistHandleService.class)
+ abstract Service bindAssistHandleService(AssistHandleService assistHandleService);
}
diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/packages/SystemUI/src/com/android/systemui/assist/IAssistHandleService.aidl
similarity index 63%
copy from wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
copy to packages/SystemUI/src/com/android/systemui/assist/IAssistHandleService.aidl
index 007ec94..ef07d9d 100644
--- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl
+++ b/packages/SystemUI/src/com/android/systemui/assist/IAssistHandleService.aidl
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2014, The Android Open Source Project
+ * Copyright (c) 2009, The Android Open 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,6 +14,11 @@
* limitations under the License.
*/
-package android.net.wifi;
+package com.android.systemui.assist;
-parcelable WifiActivityEnergyInfo;
+/** Interface implemented by AssisthandleService and called by on-device intelligence. */
+interface IAssistHandleService {
+
+ /** Request that the Assistant Handles be shown. */
+ oneway void requestAssistHandles();
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
index c0053d1..a6a3ce0 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
@@ -15,35 +15,61 @@
*/
package com.android.systemui.bubbles;
+import android.annotation.Nullable;
+import android.app.Notification;
import android.content.Context;
-import android.content.res.TypedArray;
+import android.content.pm.LauncherApps;
import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.util.AttributeSet;
+import android.util.PathParser;
import android.widget.ImageView;
import com.android.internal.graphics.ColorUtils;
+import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.DotRenderer;
+import com.android.systemui.Interpolators;
import com.android.systemui.R;
/**
- * View that circle crops its contents and supports displaying a coloured dot on a top corner.
+ * View that displays an adaptive icon with an app-badge and a dot.
+ *
+ * Dot = a small colored circle that indicates whether this bubble has an unread update.
+ * Badge = the icon associated with the app that created this bubble, this will show work profile
+ * badge if appropriate.
*/
public class BadgedImageView extends ImageView {
- private Rect mTempBounds = new Rect();
+ /** Same value as Launcher3 dot code */
+ private static final float WHITE_SCRIM_ALPHA = 0.54f;
+ /** Same as value in Launcher3 IconShape */
+ private static final int DEFAULT_PATH_SIZE = 100;
+ static final int DOT_STATE_DEFAULT = 0;
+ static final int DOT_STATE_SUPPRESSED_FOR_FLYOUT = 1;
+ static final int DOT_STATE_ANIMATING = 2;
+
+ // Flyout gets shown before the dot
+ private int mCurrentDotState = DOT_STATE_SUPPRESSED_FOR_FLYOUT;
+
+ private Bubble mBubble;
+ private BubbleIconFactory mBubbleIconFactory;
+
+ private int mIconBitmapSize;
private DotRenderer mDotRenderer;
private DotRenderer.DrawParams mDrawParams;
- private int mIconBitmapSize;
- private int mDotColor;
- private float mDotScale = 0f;
- private boolean mShowDot;
private boolean mOnLeft;
- /** Same as value in Launcher3 IconShape */
- static final int DEFAULT_PATH_SIZE = 100;
+ private int mDotColor;
+ private float mDotScale = 0f;
+ private boolean mDotDrawn;
+
+ private Rect mTempBounds = new Rect();
public BadgedImageView(Context context) {
this(context, null);
@@ -63,17 +89,19 @@
mIconBitmapSize = getResources().getDimensionPixelSize(R.dimen.bubble_icon_bitmap_size);
mDrawParams = new DotRenderer.DrawParams();
- TypedArray ta = context.obtainStyledAttributes(
- new int[]{android.R.attr.colorBackgroundFloating});
- ta.recycle();
+ Path iconPath = PathParser.createPathFromPathData(
+ getResources().getString(com.android.internal.R.string.config_icon_mask));
+ mDotRenderer = new DotRenderer(mIconBitmapSize, iconPath, DEFAULT_PATH_SIZE);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
- if (!mShowDot) {
+ if (isDotHidden()) {
+ mDotDrawn = false;
return;
}
+ mDotDrawn = mDotScale > 0.1f;
getDrawingRect(mTempBounds);
mDrawParams.color = mDotColor;
@@ -81,16 +109,29 @@
mDrawParams.leftAlign = mOnLeft;
mDrawParams.scale = mDotScale;
- if (mDotRenderer == null) {
- Path circlePath = new Path();
- float radius = DEFAULT_PATH_SIZE * 0.5f;
- circlePath.addCircle(radius /* x */, radius /* y */, radius, Path.Direction.CW);
- mDotRenderer = new DotRenderer(mIconBitmapSize, circlePath, DEFAULT_PATH_SIZE);
- }
mDotRenderer.draw(canvas, mDrawParams);
}
/**
+ * Sets the dot state, does not animate changes.
+ */
+ void setDotState(int state) {
+ mCurrentDotState = state;
+ if (state == DOT_STATE_SUPPRESSED_FOR_FLYOUT || state == DOT_STATE_DEFAULT) {
+ mDotScale = mBubble.showDot() ? 1f : 0f;
+ invalidate();
+ }
+ }
+
+ /**
+ * Whether the dot should be hidden based on current dot state.
+ */
+ private boolean isDotHidden() {
+ return (mCurrentDotState == DOT_STATE_DEFAULT && !mBubble.showDot())
+ || mCurrentDotState == DOT_STATE_SUPPRESSED_FOR_FLYOUT;
+ }
+
+ /**
* Set whether the dot should appear on left or right side of the view.
*/
void setDotOnLeft(boolean onLeft) {
@@ -98,29 +139,10 @@
invalidate();
}
- boolean getDotOnLeft() {
- return mOnLeft;
- }
-
- /**
- * Set whether the dot should show or not.
- */
- void setShowDot(boolean showDot) {
- mShowDot = showDot;
- invalidate();
- }
-
- /**
- * @return whether the dot is being displayed.
- */
- boolean isShowingDot() {
- return mShowDot;
- }
-
/**
* The colour to use for the dot.
*/
- public void setDotColor(int color) {
+ void setDotColor(int color) {
mDotColor = ColorUtils.setAlphaComponent(color, 255 /* alpha */);
invalidate();
}
@@ -128,7 +150,7 @@
/**
* @param iconPath The new icon path to use when calculating dot position.
*/
- public void drawDot(Path iconPath) {
+ void drawDot(Path iconPath) {
mDotRenderer = new DotRenderer(mIconBitmapSize, iconPath, DEFAULT_PATH_SIZE);
invalidate();
}
@@ -142,6 +164,13 @@
}
/**
+ * Whether decorations (badges or dots) are on the left.
+ */
+ boolean getDotOnLeft() {
+ return mOnLeft;
+ }
+
+ /**
* Return dot position relative to bubble view container bounds.
*/
float[] getDotCenter() {
@@ -149,11 +178,146 @@
if (mOnLeft) {
dotPosition = mDotRenderer.getLeftDotPosition();
} else {
- dotPosition = mDotRenderer.getRightDotPosition();
+ dotPosition = mDotRenderer.getRightDotPosition();
}
getDrawingRect(mTempBounds);
float dotCenterX = mTempBounds.width() * dotPosition[0];
float dotCenterY = mTempBounds.height() * dotPosition[1];
return new float[]{dotCenterX, dotCenterY};
}
+
+ /**
+ * Populates this view with a bubble.
+ * <p>
+ * This should only be called when a new bubble is being set on the view, updates to the
+ * current bubble should use {@link #update(Bubble)}.
+ *
+ * @param bubble the bubble to display in this view.
+ */
+ public void setBubble(Bubble bubble) {
+ mBubble = bubble;
+ }
+
+ /**
+ * @param factory Factory for creating normalized bubble icons.
+ */
+ public void setBubbleIconFactory(BubbleIconFactory factory) {
+ mBubbleIconFactory = factory;
+ }
+
+ /**
+ * The key for the {@link Bubble} associated with this view, if one exists.
+ */
+ @Nullable
+ public String getKey() {
+ return (mBubble != null) ? mBubble.getKey() : null;
+ }
+
+ /**
+ * Updates the UI based on the bubble, updates badge and animates messages as needed.
+ */
+ public void update(Bubble bubble) {
+ mBubble = bubble;
+ setDotState(DOT_STATE_SUPPRESSED_FOR_FLYOUT);
+ updateViews();
+ }
+
+ int getDotColor() {
+ return mDotColor;
+ }
+
+ /** Sets the position of the 'new' dot, animating it out and back in if requested. */
+ void setDotPosition(boolean onLeft, boolean animate) {
+ if (animate && onLeft != getDotOnLeft() && !isDotHidden()) {
+ animateDot(false /* showDot */, () -> {
+ setDotOnLeft(onLeft);
+ animateDot(true /* showDot */, null);
+ });
+ } else {
+ setDotOnLeft(onLeft);
+ }
+ }
+
+ boolean getDotPositionOnLeft() {
+ return getDotOnLeft();
+ }
+
+ /** Changes the dot's visibility to match the bubble view's state. */
+ void animateDot() {
+ if (mCurrentDotState == DOT_STATE_DEFAULT) {
+ animateDot(mBubble.showDot(), null);
+ }
+ }
+
+ /**
+ * Animates the dot to show or hide.
+ */
+ private void animateDot(boolean showDot, Runnable after) {
+ if (mDotDrawn == showDot) {
+ // State is consistent, do nothing.
+ return;
+ }
+
+ setDotState(DOT_STATE_ANIMATING);
+
+ // Do NOT wait until after animation ends to setShowDot
+ // to avoid overriding more recent showDot states.
+ clearAnimation();
+ animate().setDuration(200)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .setUpdateListener((valueAnimator) -> {
+ float fraction = valueAnimator.getAnimatedFraction();
+ fraction = showDot ? fraction : 1f - fraction;
+ setDotScale(fraction);
+ }).withEndAction(() -> {
+ setDotScale(showDot ? 1f : 0f);
+ setDotState(DOT_STATE_DEFAULT);
+ if (after != null) {
+ after.run();
+ }
+ }).start();
+ }
+
+ void updateViews() {
+ if (mBubble == null || mBubbleIconFactory == null) {
+ return;
+ }
+
+ Drawable bubbleDrawable = getBubbleDrawable(mContext);
+ BitmapInfo badgeBitmapInfo = mBubbleIconFactory.getBadgedBitmap(mBubble);
+ BitmapInfo bubbleBitmapInfo = mBubbleIconFactory.getBubbleBitmap(bubbleDrawable,
+ badgeBitmapInfo);
+ setImageBitmap(bubbleBitmapInfo.icon);
+
+ // Update badge.
+ mDotColor = ColorUtils.blendARGB(badgeBitmapInfo.color, Color.WHITE, WHITE_SCRIM_ALPHA);
+ setDotColor(mDotColor);
+
+ // Update dot.
+ Path iconPath = PathParser.createPathFromPathData(
+ getResources().getString(com.android.internal.R.string.config_icon_mask));
+ Matrix matrix = new Matrix();
+ float scale = mBubbleIconFactory.getNormalizer().getScale(bubbleDrawable,
+ null /* outBounds */, null /* path */, null /* outMaskShape */);
+ float radius = BadgedImageView.DEFAULT_PATH_SIZE / 2f;
+ matrix.setScale(scale /* x scale */, scale /* y scale */, radius /* pivot x */,
+ radius /* pivot y */);
+ iconPath.transform(matrix);
+ drawDot(iconPath);
+
+ animateDot();
+ }
+
+ Drawable getBubbleDrawable(Context context) {
+ if (mBubble.getShortcutInfo() != null && mBubble.usingShortcutInfo()) {
+ LauncherApps launcherApps =
+ (LauncherApps) getContext().getSystemService(Context.LAUNCHER_APPS_SERVICE);
+ int density = getContext().getResources().getConfiguration().densityDpi;
+ return launcherApps.getShortcutIconDrawable(mBubble.getShortcutInfo(), density);
+ } else {
+ Notification.BubbleMetadata metadata = mBubble.getEntry().getBubbleMetadata();
+ Icon ic = metadata.getIcon();
+ return ic.loadDrawable(context);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index 24ee9695..f3a7ca9 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -64,8 +64,9 @@
private ShortcutInfo mShortcutInfo;
private boolean mInflated;
- private BubbleView mIconView;
+ private BadgedImageView mIconView;
private BubbleExpandedView mExpandedView;
+ private BubbleIconFactory mBubbleIconFactory;
private long mLastUpdated;
private long mLastAccessed;
@@ -146,7 +147,7 @@
return mAppName;
}
- public Drawable getUserBadgedAppIcon() {
+ Drawable getUserBadgedAppIcon() {
return mUserBadgedAppIcon;
}
@@ -165,17 +166,15 @@
return BubbleExperimentConfig.isShortcutIntent(getBubbleIntent());
}
+ void setBubbleIconFactory(BubbleIconFactory factory) {
+ mBubbleIconFactory = factory;
+ }
+
boolean isInflated() {
return mInflated;
}
- void updateDotVisibility() {
- if (mIconView != null) {
- mIconView.updateDotVisibility(true /* animate */);
- }
- }
-
- BubbleView getIconView() {
+ BadgedImageView getIconView() {
return mIconView;
}
@@ -193,13 +192,14 @@
if (mInflated) {
return;
}
- mIconView = (BubbleView) inflater.inflate(
+ mIconView = (BadgedImageView) inflater.inflate(
R.layout.bubble_view, stackView, false /* attachToRoot */);
+ mIconView.setBubbleIconFactory(mBubbleIconFactory);
mIconView.setBubble(this);
mExpandedView = (BubbleExpandedView) inflater.inflate(
R.layout.bubble_expanded_view, stackView, false /* attachToRoot */);
- mExpandedView.setBubble(this, stackView, mAppName);
+ mExpandedView.setBubble(this, stackView);
mInflated = true;
}
@@ -260,15 +260,15 @@
*/
void markAsAccessedAt(long lastAccessedMillis) {
mLastAccessed = lastAccessedMillis;
- setShowInShadeWhenBubble(false);
- setShowBubbleDot(false);
+ setShowInShade(false);
+ setShowDot(false /* show */, true /* animate */);
}
/**
* Whether this notification should be shown in the shade when it is also displayed as a
* bubble.
*/
- boolean showInShadeWhenBubble() {
+ boolean showInShade() {
return !mEntry.isRowDismissed() && !shouldSuppressNotification()
&& (!mEntry.isClearable() || mShowInShadeWhenBubble);
}
@@ -277,28 +277,33 @@
* Sets whether this notification should be shown in the shade when it is also displayed as a
* bubble.
*/
- void setShowInShadeWhenBubble(boolean showInShade) {
+ void setShowInShade(boolean showInShade) {
mShowInShadeWhenBubble = showInShade;
}
/**
* Sets whether the bubble for this notification should show a dot indicating updated content.
*/
- void setShowBubbleDot(boolean showDot) {
+ void setShowDot(boolean showDot, boolean animate) {
mShowBubbleUpdateDot = showDot;
+ if (animate && mIconView != null) {
+ mIconView.animateDot();
+ } else if (mIconView != null) {
+ mIconView.invalidate();
+ }
}
/**
* Whether the bubble for this notification should show a dot indicating updated content.
*/
- boolean showBubbleDot() {
+ boolean showDot() {
return mShowBubbleUpdateDot && !mEntry.shouldSuppressNotificationDot();
}
/**
* Whether the flyout for the bubble should be shown.
*/
- boolean showFlyoutForBubble() {
+ boolean showFlyout() {
return !mSuppressFlyout && !mEntry.shouldSuppressPeek()
&& !mEntry.shouldSuppressNotificationList();
}
@@ -470,9 +475,9 @@
public void dump(
@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
pw.print("key: "); pw.println(mKey);
- pw.print(" showInShade: "); pw.println(showInShadeWhenBubble());
- pw.print(" showDot: "); pw.println(showBubbleDot());
- pw.print(" showFlyout: "); pw.println(showFlyoutForBubble());
+ pw.print(" showInShade: "); pw.println(showInShade());
+ pw.print(" showDot: "); pw.println(showDot());
+ pw.print(" showFlyout: "); pw.println(showFlyout());
pw.print(" desiredHeight: "); pw.println(getDesiredHeightString());
pw.print(" suppressNotif: "); pw.println(shouldSuppressNotification());
pw.print(" autoExpand: "); pw.println(shouldAutoExpand());
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index ed21e14..dbb1936 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -251,15 +251,15 @@
mZenModeController.addCallback(new ZenModeController.Callback() {
@Override
public void onZenChanged(int zen) {
- if (mStackView != null) {
- mStackView.updateDots();
+ for (Bubble b : mBubbleData.getBubbles()) {
+ b.setShowDot(b.showInShade(), true /* animate */);
}
}
@Override
public void onConfigChanged(ZenModeConfig config) {
- if (mStackView != null) {
- mStackView.updateDots();
+ for (Bubble b : mBubbleData.getBubbles()) {
+ b.setShowDot(b.showInShade(), true /* animate */);
}
}
});
@@ -465,7 +465,7 @@
*/
public boolean isBubbleNotificationSuppressedFromShade(String key) {
boolean isBubbleAndSuppressed = mBubbleData.hasBubbleWithKey(key)
- && !mBubbleData.getBubbleWithKey(key).showInShadeWhenBubble();
+ && !mBubbleData.getBubbleWithKey(key).showInShade();
NotificationEntry entry = mNotificationEntryManager.getActiveNotificationUnfiltered(key);
String groupKey = entry != null ? entry.getSbn().getGroupKey() : null;
boolean isSuppressedSummary = mBubbleData.isSummarySuppressed(groupKey);
@@ -630,11 +630,8 @@
Bubble bubble = mBubbleData.getBubbleWithKey(key);
boolean bubbleExtended = entry != null && entry.isBubble() && userRemovedNotif;
if (bubbleExtended) {
- bubble.setShowInShadeWhenBubble(false);
- bubble.setShowBubbleDot(false);
- if (mStackView != null) {
- mStackView.updateDotVisibility(entry.getKey());
- }
+ bubble.setShowInShade(false);
+ bubble.setShowDot(false /* show */, true /* animate */);
mNotificationEntryManager.updateNotifications(
"BubbleController.onNotificationRemoveRequested");
return true;
@@ -660,11 +657,8 @@
// As far as group manager is concerned, once a child is no longer shown
// in the shade, it is essentially removed.
mNotificationGroupManager.onEntryRemoved(bubbleChild.getEntry());
- bubbleChild.setShowInShadeWhenBubble(false);
- bubbleChild.setShowBubbleDot(false);
- if (mStackView != null) {
- mStackView.updateDotVisibility(bubbleChild.getKey());
- }
+ bubbleChild.setShowInShade(false);
+ bubbleChild.setShowDot(false /* show */, true /* animate */);
}
// And since all children are removed, remove the summary.
mNotificationGroupManager.onEntryRemoved(summary);
@@ -700,10 +694,15 @@
@Override
public void onPendingEntryAdded(NotificationEntry entry) {
boolean previouslyUserCreated = mUserCreatedBubbles.contains(entry.getKey());
- BubbleExperimentConfig.adjustForExperiments(mContext, entry, previouslyUserCreated);
+ boolean wasAdjusted = BubbleExperimentConfig.adjustForExperiments(
+ mContext, entry, previouslyUserCreated);
if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
- && canLaunchInActivityView(mContext, entry)) {
+ && (canLaunchInActivityView(mContext, entry) || wasAdjusted)) {
+ if (wasAdjusted && !previouslyUserCreated) {
+ // Gotta treat the auto-bubbled / whitelisted packaged bubbles as usercreated
+ mUserCreatedBubbles.add(entry.getKey());
+ }
updateBubble(entry);
}
}
@@ -711,14 +710,19 @@
@Override
public void onPreEntryUpdated(NotificationEntry entry) {
boolean previouslyUserCreated = mUserCreatedBubbles.contains(entry.getKey());
- BubbleExperimentConfig.adjustForExperiments(mContext, entry, previouslyUserCreated);
+ boolean wasAdjusted = BubbleExperimentConfig.adjustForExperiments(
+ mContext, entry, previouslyUserCreated);
boolean shouldBubble = mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
- && canLaunchInActivityView(mContext, entry);
+ && (canLaunchInActivityView(mContext, entry) || wasAdjusted);
if (!shouldBubble && mBubbleData.hasBubbleWithKey(entry.getKey())) {
// It was previously a bubble but no longer a bubble -- lets remove it
removeBubble(entry.getKey(), DISMISS_NO_LONGER_BUBBLE);
} else if (shouldBubble) {
+ if (wasAdjusted && !previouslyUserCreated) {
+ // Gotta treat the auto-bubbled / whitelisted packaged bubbles as usercreated
+ mUserCreatedBubbles.add(entry.getKey());
+ }
updateBubble(entry);
}
}
@@ -765,7 +769,7 @@
// If the bubble is removed for user switching, leave the notification in place.
if (reason != DISMISS_USER_CHANGED) {
if (!mBubbleData.hasBubbleWithKey(bubble.getKey())
- && !bubble.showInShadeWhenBubble()) {
+ && !bubble.showInShade()) {
// The bubble is gone & the notification is gone, time to actually remove it
mNotificationEntryManager.performRemoveNotification(
bubble.getEntry().getSbn(), UNDEFINED_DISMISS_REASON);
@@ -1022,11 +1026,6 @@
PendingIntent intent = entry.getBubbleMetadata() != null
? entry.getBubbleMetadata().getIntent()
: null;
- return canLaunchIntentInActivityView(context, entry, intent);
- }
-
- static boolean canLaunchIntentInActivityView(Context context, NotificationEntry entry,
- PendingIntent intent) {
if (intent == null) {
Log.w(TAG, "Unable to create bubble -- no intent: " + entry.getKey());
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index 2ca993b..034bff3 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -210,8 +210,8 @@
setSelectedBubbleInternal(bubble);
}
boolean isBubbleExpandedAndSelected = mExpanded && mSelectedBubble == bubble;
- bubble.setShowInShadeWhenBubble(!isBubbleExpandedAndSelected && showInShade);
- bubble.setShowBubbleDot(!isBubbleExpandedAndSelected);
+ bubble.setShowInShade(!isBubbleExpandedAndSelected && showInShade);
+ bubble.setShowDot(!isBubbleExpandedAndSelected /* show */, true /* animate */);
dispatchPendingChanges();
}
@@ -303,9 +303,8 @@
if (notif.getRanking().visuallyInterruptive()) {
return true;
}
- final boolean suppressedFromShade = hasBubbleWithKey(notif.getKey())
- && !getBubbleWithKey(notif.getKey()).showInShadeWhenBubble();
- return suppressedFromShade;
+ return hasBubbleWithKey(notif.getKey())
+ && !getBubbleWithKey(notif.getKey()).showInShade();
}
private void doAdd(Bubble bubble) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 512b38e..efc955d 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -31,15 +31,12 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.os.RemoteException;
import android.service.notification.StatusBarNotification;
@@ -102,9 +99,7 @@
private int mExpandedViewTouchSlop;
private Bubble mBubble;
- private PackageManager mPm;
private String mAppName;
- private Drawable mAppIcon;
private BubbleController mBubbleController = Dependency.get(BubbleController.class);
private WindowManager mWindowManager;
@@ -212,7 +207,6 @@
public BubbleExpandedView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- mPm = context.getPackageManager();
mDisplaySize = new Point();
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
// Get the real size -- this includes screen decorations (notches, statusbar, navbar).
@@ -350,29 +344,14 @@
/**
* Sets the bubble used to populate this view.
*/
- public void setBubble(Bubble bubble, BubbleStackView stackView, String appName) {
+ public void setBubble(Bubble bubble, BubbleStackView stackView) {
if (DEBUG_BUBBLE_EXPANDED_VIEW) {
Log.d(TAG, "setBubble: bubble=" + (bubble != null ? bubble.getKey() : "null"));
}
-
mStackView = stackView;
mBubble = bubble;
- mAppName = appName;
+ mAppName = bubble.getAppName();
- try {
- ApplicationInfo info = mPm.getApplicationInfo(
- bubble.getPackageName(),
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_DISABLED_COMPONENTS
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.MATCH_DIRECT_BOOT_AWARE);
- mAppIcon = mPm.getApplicationIcon(info);
- } catch (PackageManager.NameNotFoundException e) {
- // Do nothing.
- }
- if (mAppIcon == null) {
- mAppIcon = mPm.getDefaultActivityIcon();
- }
applyThemeAttrs();
showSettingsIcon();
updateExpandedView();
@@ -624,7 +603,7 @@
action,
mStackView.getNormalizedXPosition(),
mStackView.getNormalizedYPosition(),
- bubble.showInShadeWhenBubble(),
+ bubble.showInShade(),
bubble.isOngoing(),
false /* isAppForeground (unused) */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java
index 17d6737..e138d93 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java
@@ -21,7 +21,6 @@
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST;
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED;
-import static com.android.systemui.bubbles.BubbleController.canLaunchIntentInActivityView;
import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_EXPERIMENTS;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
@@ -62,11 +61,13 @@
private static final boolean ALLOW_ANY_NOTIF_TO_BUBBLE_DEFAULT = false;
private static final String ALLOW_MESSAGE_NOTIFS_TO_BUBBLE = "allow_message_notifs_to_bubble";
- private static final boolean ALLOW_MESSAGE_NOTIFS_TO_BUBBLE_DEFAULT = false;
+ private static final boolean ALLOW_MESSAGE_NOTIFS_TO_BUBBLE_DEFAULT = true;
private static final String ALLOW_SHORTCUTS_TO_BUBBLE = "allow_shortcuts_to_bubble";
private static final boolean ALLOW_SHORTCUT_TO_BUBBLE_DEFAULT = false;
+ private static final String WHITELISTED_AUTO_BUBBLE_APPS = "whitelisted_auto_bubble_apps";
+
/**
* When true, if a notification has the information necessary to bubble (i.e. valid
* contentIntent and an icon or image), then a {@link android.app.Notification.BubbleMetadata}
@@ -104,14 +105,36 @@
}
/**
+ * Returns whether the provided package is whitelisted to bubble.
+ */
+ static boolean isPackageWhitelistedToAutoBubble(Context context, String packageName) {
+ String unsplitList = Settings.Secure.getString(context.getContentResolver(),
+ WHITELISTED_AUTO_BUBBLE_APPS);
+ if (unsplitList != null) {
+ // We expect the list to be separated by commas and no white space (but we trim in case)
+ String[] packageList = unsplitList.split(",");
+ for (int i = 0; i < packageList.length; i++) {
+ if (packageList[i].trim().equals(packageName)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
* If {@link #allowAnyNotifToBubble(Context)} is true, this method creates and adds
* {@link android.app.Notification.BubbleMetadata} to the notification entry as long as
* the notification has necessary info for BubbleMetadata.
+ *
+ * @return whether an adjustment was made.
*/
- static void adjustForExperiments(Context context, NotificationEntry entry,
+ static boolean adjustForExperiments(Context context, NotificationEntry entry,
boolean previouslyUserCreated) {
Notification.BubbleMetadata metadata = null;
boolean addedMetadata = false;
+ boolean whiteListedToAutoBubble =
+ isPackageWhitelistedToAutoBubble(context, entry.getSbn().getPackageName());
Notification notification = entry.getSbn().getNotification();
boolean isMessage = Notification.MessagingStyle.class.equals(
@@ -169,14 +192,16 @@
}
}
- if (previouslyUserCreated && addedMetadata) {
- // Update to a previous bubble, set its flag now so the update goes
- // to the bubble.
+ boolean bubbleForWhitelist = whiteListedToAutoBubble && (addedMetadata || hasMetadata);
+ if ((previouslyUserCreated && addedMetadata) || bubbleForWhitelist) {
+ // Update to a previous bubble (or new autobubble), set its flag now.
if (DEBUG_EXPERIMENTS) {
Log.d(TAG, "Setting FLAG_BUBBLE for: " + entry.getKey());
}
entry.setFlagBubble(true);
+ return true;
}
+ return addedMetadata;
}
static Notification.BubbleMetadata createFromNotif(Context context, NotificationEntry entry) {
@@ -193,7 +218,7 @@
? notification.getLargeIcon()
: notification.getSmallIcon();
}
- if (canLaunchIntentInActivityView(context, entry, intent)) {
+ if (intent != null) {
return new Notification.BubbleMetadata.Builder()
.setDesiredHeight(BUBBLE_HEIGHT)
.setIcon(icon)
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java
index 58f3f22..78e98eb 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java
@@ -206,7 +206,7 @@
void setupFlyoutStartingAsDot(
CharSequence updateMessage, PointF stackPos, float parentWidth,
boolean arrowPointingLeft, int dotColor, @Nullable Runnable onLayoutComplete,
- @Nullable Runnable onHide, float[] dotCenter) {
+ @Nullable Runnable onHide, float[] dotCenter, boolean hideDot) {
mArrowPointingLeft = arrowPointingLeft;
mDotColor = dotColor;
mOnHide = onHide;
@@ -242,12 +242,14 @@
// Calculate the difference in size between the flyout and the 'dot' so that we can
// transform into the dot later.
- mFlyoutToDotWidthDelta = getWidth() - mNewDotSize;
- mFlyoutToDotHeightDelta = getHeight() - mNewDotSize;
+ final float newDotSize = hideDot ? 0f : mNewDotSize;
+ mFlyoutToDotWidthDelta = getWidth() - newDotSize;
+ mFlyoutToDotHeightDelta = getHeight() - newDotSize;
// Calculate the translation values needed to be in the correct 'new dot' position.
- final float dotPositionX = stackPos.x + mDotCenter[0] - (mOriginalDotSize / 2f);
- final float dotPositionY = stackPos.y + mDotCenter[1] - (mOriginalDotSize / 2f);
+ final float adjustmentForScaleAway = hideDot ? 0f : (mOriginalDotSize / 2f);
+ final float dotPositionX = stackPos.x + mDotCenter[0] - adjustmentForScaleAway;
+ final float dotPositionY = stackPos.y + mDotCenter[1] - adjustmentForScaleAway;
final float distanceFromFlyoutLeftToDotCenterX = mRestingTranslationX - dotPositionX;
final float distanceFromLayoutTopToDotCenterY = restingTranslationY - dotPositionY;
@@ -319,8 +321,7 @@
// percentage.
final float width = getWidth() - (mFlyoutToDotWidthDelta * mPercentTransitionedToDot);
final float height = getHeight() - (mFlyoutToDotHeightDelta * mPercentTransitionedToDot);
- final float interpolatedRadius = mNewDotRadius * mPercentTransitionedToDot
- + mCornerRadius * (1 - mPercentTransitionedToDot);
+ final float interpolatedRadius = getInterpolatedRadius();
// Translate the flyout background towards the collapsed 'dot' state.
mBgTranslationX = mTranslationXWhenDot * mPercentTransitionedToDot;
@@ -387,8 +388,7 @@
if (!mTriangleOutline.isEmpty()) {
// Draw the rect into the outline as a path so we can merge the triangle path into it.
final Path rectPath = new Path();
- final float interpolatedRadius = mNewDotRadius * mPercentTransitionedToDot
- + mCornerRadius * (1 - mPercentTransitionedToDot);
+ final float interpolatedRadius = getInterpolatedRadius();
rectPath.addRoundRect(mBgRect, interpolatedRadius,
interpolatedRadius, Path.Direction.CW);
outline.setConvexPath(rectPath);
@@ -420,4 +420,9 @@
outline.mPath.transform(outlineMatrix);
}
}
+
+ private float getInterpolatedRadius() {
+ return mNewDotRadius * mPercentTransitionedToDot
+ + mCornerRadius * (1 - mPercentTransitionedToDot);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
index a1c77c0..9ff033c 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
@@ -16,8 +16,14 @@
package com.android.systemui.bubbles;
import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import com.android.launcher3.icons.BaseIconFactory;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.ShadowGenerator;
import com.android.systemui.R;
/**
@@ -26,13 +32,37 @@
* so there is no need to manage a pool across multiple threads.
*/
public class BubbleIconFactory extends BaseIconFactory {
+
protected BubbleIconFactory(Context context) {
super(context, context.getResources().getConfiguration().densityDpi,
context.getResources().getDimensionPixelSize(R.dimen.individual_bubble_size));
}
- public int getBadgeSize() {
+ int getBadgeSize() {
return mContext.getResources().getDimensionPixelSize(
com.android.launcher3.icons.R.dimen.profile_badge_size);
}
+
+ BitmapInfo getBadgedBitmap(Bubble b) {
+ Bitmap userBadgedBitmap = createIconBitmap(
+ b.getUserBadgedAppIcon(), 1f, getBadgeSize());
+
+ Canvas c = new Canvas();
+ ShadowGenerator shadowGenerator = new ShadowGenerator(getBadgeSize());
+ c.setBitmap(userBadgedBitmap);
+ shadowGenerator.recreateIcon(Bitmap.createBitmap(userBadgedBitmap), c);
+ BitmapInfo bitmapInfo = createIconBitmap(userBadgedBitmap);
+ return bitmapInfo;
+ }
+
+ BitmapInfo getBubbleBitmap(Drawable bubble, BitmapInfo badge) {
+ BitmapInfo bubbleIconInfo = createBadgedIconBitmap(bubble,
+ null /* user */,
+ true /* shrinkNonAdaptiveIcons */);
+
+ badgeWithDrawable(bubbleIconInfo.icon,
+ new BitmapDrawable(mContext.getResources(), badge.icon));
+ return bubbleIconInfo;
+ }
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 4a1bbe4..29de2f0 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -19,6 +19,8 @@
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static com.android.systemui.bubbles.BadgedImageView.DOT_STATE_DEFAULT;
+import static com.android.systemui.bubbles.BadgedImageView.DOT_STATE_SUPPRESSED_FOR_FLYOUT;
import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_STACK_VIEW;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
@@ -169,7 +171,7 @@
* Callback to run after the flyout hides. Also called if a new flyout is shown before the
* previous one animates out.
*/
- private Runnable mFlyoutOnHide;
+ private Runnable mAfterFlyoutHidden;
/** Layout change listener that moves the stack to the nearest valid position on rotation. */
private OnLayoutChangeListener mOrientationChangedListener;
@@ -674,18 +676,6 @@
}
/**
- * Updates the visibility of the 'dot' indicating an update on the bubble.
- *
- * @param key the {@link NotificationEntry#key} associated with the bubble.
- */
- public void updateDotVisibility(String key) {
- Bubble b = mBubbleData.getBubbleWithKey(key);
- if (b != null) {
- b.updateDotVisibility();
- }
- }
-
- /**
* Sets the listener to notify when the bubble stack is expanded.
*/
public void setExpandListener(BubbleController.BubbleExpandListener listener) {
@@ -707,9 +697,9 @@
}
/**
- * The {@link BubbleView} that is expanded, null if one does not exist.
+ * The {@link BadgedImageView} that is expanded, null if one does not exist.
*/
- BubbleView getExpandedBubbleView() {
+ BadgedImageView getExpandedBubbleView() {
return mExpandedBubble != null ? mExpandedBubble.getIconView() : null;
}
@@ -731,7 +721,7 @@
Bubble bubbleToExpand = mBubbleData.getBubbleWithKey(key);
if (bubbleToExpand != null) {
setSelectedBubble(bubbleToExpand);
- bubbleToExpand.setShowInShadeWhenBubble(false);
+ bubbleToExpand.setShowInShade(false);
setExpanded(true);
}
}
@@ -746,8 +736,8 @@
mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
}
+ bubble.setBubbleIconFactory(mBubbleIconFactory);
bubble.inflate(mInflater, this);
- bubble.getIconView().setBubbleIconFactory(mBubbleIconFactory);
bubble.getIconView().updateViews();
// Set the dot position to the opposite of the side the stack is resting on, since the stack
@@ -884,7 +874,7 @@
if (isIntersecting(mBubbleContainer, x, y)) {
// Could be tapping or dragging a bubble while expanded
for (int i = 0; i < mBubbleContainer.getChildCount(); i++) {
- BubbleView view = (BubbleView) mBubbleContainer.getChildAt(i);
+ BadgedImageView view = (BadgedImageView) mBubbleContainer.getChildAt(i);
if (isIntersecting(view, x, y)) {
return view;
}
@@ -1028,9 +1018,9 @@
}
/** Return the BubbleView at the given index from the bubble container. */
- public BubbleView getBubbleAt(int i) {
+ public BadgedImageView getBubbleAt(int i) {
return mBubbleContainer.getChildCount() > i
- ? (BubbleView) mBubbleContainer.getChildAt(i)
+ ? (BadgedImageView) mBubbleContainer.getChildAt(i)
: null;
}
@@ -1382,16 +1372,6 @@
: 0f);
}
- /** Updates the dot visibility, this is used in response to a zen mode config change. */
- void updateDots() {
- int bubbsCount = mBubbleContainer.getChildCount();
- for (int i = 0; i < bubbsCount; i++) {
- BubbleView bv = (BubbleView) mBubbleContainer.getChildAt(i);
- // If nothing changed the animation won't happen
- bv.updateDotVisibility(true /* animate */);
- }
- }
-
/**
* Calculates the y position of the expanded view when it is expanded.
*/
@@ -1405,37 +1385,40 @@
@VisibleForTesting
void animateInFlyoutForBubble(Bubble bubble) {
final CharSequence updateMessage = bubble.getUpdateMessage(getContext());
- if (!bubble.showFlyoutForBubble()) {
- // In case flyout was suppressed for this update, reset now.
- bubble.setSuppressFlyout(false);
- return;
- }
+ final BadgedImageView bubbleView = bubble.getIconView();
if (updateMessage == null
+ || !bubble.showFlyout()
|| isExpanded()
|| mIsExpansionAnimating
|| mIsGestureInProgress
|| mBubbleToExpandAfterFlyoutCollapse != null
- || bubble.getIconView() == null) {
+ || bubbleView == null) {
+ if (bubbleView != null) {
+ bubbleView.setDotState(DOT_STATE_DEFAULT);
+ }
// Skip the message if none exists, we're expanded or animating expansion, or we're
// about to expand a bubble from the previous tapped flyout, or if bubble view is null.
return;
}
+
mFlyoutDragDeltaX = 0f;
clearFlyoutOnHide();
- mFlyoutOnHide = () -> {
- resetDot(bubble);
- if (mBubbleToExpandAfterFlyoutCollapse == null) {
- return;
+ mAfterFlyoutHidden = () -> {
+ // Null it out to ensure it runs once.
+ mAfterFlyoutHidden = null;
+
+ if (mBubbleToExpandAfterFlyoutCollapse != null) {
+ // User tapped on the flyout and we should expand
+ mBubbleData.setSelectedBubble(mBubbleToExpandAfterFlyoutCollapse);
+ mBubbleData.setExpanded(true);
+ mBubbleToExpandAfterFlyoutCollapse = null;
}
- mBubbleData.setSelectedBubble(mBubbleToExpandAfterFlyoutCollapse);
- mBubbleData.setExpanded(true);
- mBubbleToExpandAfterFlyoutCollapse = null;
+ bubbleView.setDotState(DOT_STATE_DEFAULT);
};
mFlyout.setVisibility(INVISIBLE);
- // Temporarily suppress the dot while the flyout is visible.
- bubble.getIconView().setSuppressDot(
- true /* suppressDot */, false /* animate */);
+ // Don't show the dot when we're animating the flyout
+ bubbleView.setDotState(DOT_STATE_SUPPRESSED_FOR_FLYOUT);
// Start flyout expansion. Post in case layout isn't complete and getWidth returns 0.
post(() -> {
@@ -1461,8 +1444,9 @@
mStackAnimationController.isStackOnLeftSide(),
bubble.getIconView().getDotColor() /* dotColor */,
expandFlyoutAfterDelay /* onLayoutComplete */,
- mFlyoutOnHide,
- bubble.getIconView().getDotCenter());
+ mAfterFlyoutHidden,
+ bubble.getIconView().getDotCenter(),
+ !bubble.showDot());
mFlyout.bringToFront();
});
mFlyout.removeCallbacks(mHideFlyout);
@@ -1470,24 +1454,6 @@
logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__FLYOUT);
}
- private void resetDot(Bubble bubble) {
- final boolean suppressDot = !bubble.showBubbleDot();
- // If we're going to suppress the dot, make it visible first so it'll
- // visibly animate away.
-
- if (suppressDot) {
- bubble.getIconView().setSuppressDot(
- false /* suppressDot */, false /* animate */);
- }
- // Reset dot suppression. If we're not suppressing due to DND, then
- // stop suppressing it with no animation (since the flyout has
- // transformed into the dot). If we are suppressing due to DND, animate
- // it away.
- bubble.getIconView().setSuppressDot(
- suppressDot /* suppressDot */,
- suppressDot /* animate */);
- }
-
/** Hide the flyout immediately and cancel any pending hide runnables. */
private void hideFlyoutImmediate() {
clearFlyoutOnHide();
@@ -1498,11 +1464,11 @@
private void clearFlyoutOnHide() {
mFlyout.removeCallbacks(mAnimateInFlyout);
- if (mFlyoutOnHide == null) {
+ if (mAfterFlyoutHidden == null) {
return;
}
- mFlyoutOnHide.run();
- mFlyoutOnHide = null;
+ mAfterFlyoutHidden.run();
+ mAfterFlyoutHidden = null;
}
@Override
@@ -1599,8 +1565,7 @@
private void updateBubbleZOrdersAndDotPosition(boolean animate) {
int bubbleCount = mBubbleContainer.getChildCount();
for (int i = 0; i < bubbleCount; i++) {
- BubbleView bv = (BubbleView) mBubbleContainer.getChildAt(i);
- bv.updateDotVisibility(true /* animate */);
+ BadgedImageView bv = (BadgedImageView) mBubbleContainer.getChildAt(i);
bv.setZ((mMaxBubbles * mBubbleElevation) - i);
// If the dot is on the left, and so is the stack, we need to change the dot position.
if (bv.getDotPositionOnLeft() == mStackOnLeftOrWillBe) {
@@ -1705,7 +1670,7 @@
action,
getNormalizedXPosition(),
getNormalizedYPosition(),
- bubble.showInShadeWhenBubble(),
+ bubble.showInShade(),
bubble.isOngoing(),
false /* isAppForeground (unused) */);
}
@@ -1727,8 +1692,8 @@
List<Bubble> bubbles = new ArrayList<>();
for (int i = 0; i < mBubbleContainer.getChildCount(); i++) {
View child = mBubbleContainer.getChildAt(i);
- if (child instanceof BubbleView) {
- String key = ((BubbleView) child).getKey();
+ if (child instanceof BadgedImageView) {
+ String key = ((BadgedImageView) child).getKey();
Bubble bubble = mBubbleData.getBubbleWithKey(key);
bubbles.add(bubble);
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
index 4240e06..44e013a 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
@@ -95,7 +95,7 @@
return false;
}
- if (!(mTouchedView instanceof BubbleView)
+ if (!(mTouchedView instanceof BadgedImageView)
&& !(mTouchedView instanceof BubbleStackView)
&& !(mTouchedView instanceof BubbleFlyoutView)) {
// Not touching anything touchable, but we shouldn't collapse (e.g. touching edge
@@ -187,7 +187,7 @@
mStack.onFlyoutDragFinished(rawX - mTouchDown.x /* deltaX */, velX);
} else if (shouldDismiss) {
final String individualBubbleKey =
- isStack ? null : ((BubbleView) mTouchedView).getKey();
+ isStack ? null : ((BadgedImageView) mTouchedView).getKey();
mStack.magnetToStackIfNeededThenAnimateDismissal(mTouchedView, velX, velY,
() -> {
if (isStack) {
@@ -214,7 +214,7 @@
// Toggle expansion
mBubbleData.setExpanded(!mBubbleData.isExpanded());
} else {
- final String key = ((BubbleView) mTouchedView).getKey();
+ final String key = ((BadgedImageView) mTouchedView).getKey();
mBubbleData.setSelectedBubble(mBubbleData.getBubbleWithKey(key));
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
deleted file mode 100644
index 79807b3..0000000
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.bubbles;
-
-import android.annotation.Nullable;
-import android.app.Notification;
-import android.content.Context;
-import android.content.pm.LauncherApps;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.Path;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
-import android.util.AttributeSet;
-import android.util.PathParser;
-import android.widget.FrameLayout;
-
-import com.android.internal.graphics.ColorUtils;
-import com.android.launcher3.icons.BitmapInfo;
-import com.android.launcher3.icons.ColorExtractor;
-import com.android.launcher3.icons.ShadowGenerator;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-
-/**
- * A floating object on the screen that can post message updates.
- */
-public class BubbleView extends FrameLayout {
-
- // Same value as Launcher3 badge code
- private static final float WHITE_SCRIM_ALPHA = 0.54f;
- private Context mContext;
-
- private BadgedImageView mBadgedImageView;
- private int mDotColor;
- private ColorExtractor mColorExtractor;
-
- // mBubbleIconFactory cannot be static because it depends on Context.
- private BubbleIconFactory mBubbleIconFactory;
-
- private boolean mSuppressDot;
-
- private Bubble mBubble;
-
- public BubbleView(Context context) {
- this(context, null);
- }
-
- public BubbleView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public BubbleView(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public BubbleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- mContext = context;
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mBadgedImageView = findViewById(R.id.bubble_image);
- mColorExtractor = new ColorExtractor();
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- }
-
- /**
- * Populates this view with a bubble.
- * <p>
- * This should only be called when a new bubble is being set on the view, updates to the
- * current bubble should use {@link #update(Bubble)}.
- *
- * @param bubble the bubble to display in this view.
- */
- public void setBubble(Bubble bubble) {
- mBubble = bubble;
- }
-
- /**
- * @param factory Factory for creating normalized bubble icons.
- */
- public void setBubbleIconFactory(BubbleIconFactory factory) {
- mBubbleIconFactory = factory;
- }
-
- /**
- * The {@link NotificationEntry} associated with this view, if one exists.
- */
- @Nullable
- public NotificationEntry getEntry() {
- return mBubble != null ? mBubble.getEntry() : null;
- }
-
- /**
- * The key for the {@link NotificationEntry} associated with this view, if one exists.
- */
- @Nullable
- public String getKey() {
- return (mBubble != null) ? mBubble.getKey() : null;
- }
-
- /**
- * Updates the UI based on the bubble, updates badge and animates messages as needed.
- */
- public void update(Bubble bubble) {
- mBubble = bubble;
- updateViews();
- }
-
- /** Changes the dot's visibility to match the bubble view's state. */
- void updateDotVisibility(boolean animate) {
- updateDotVisibility(animate, null /* after */);
- }
-
- /**
- * Sets whether or not to hide the dot even if we'd otherwise show it. This is used while the
- * flyout is visible or animating, to hide the dot until the flyout visually transforms into it.
- */
- void setSuppressDot(boolean suppressDot, boolean animate) {
- mSuppressDot = suppressDot;
- updateDotVisibility(animate);
- }
-
- boolean isDotShowing() {
- return mBubble.showBubbleDot() && !mSuppressDot;
- }
-
- int getDotColor() {
- return mDotColor;
- }
-
- /** Sets the position of the 'new' dot, animating it out and back in if requested. */
- void setDotPosition(boolean onLeft, boolean animate) {
- if (animate && onLeft != mBadgedImageView.getDotOnLeft() && isDotShowing()) {
- animateDot(false /* showDot */, () -> {
- mBadgedImageView.setDotOnLeft(onLeft);
- animateDot(true /* showDot */, null);
- });
- } else {
- mBadgedImageView.setDotOnLeft(onLeft);
- }
- }
-
- float[] getDotCenter() {
- float[] unscaled = mBadgedImageView.getDotCenter();
- return new float[]{unscaled[0], unscaled[1]};
- }
-
- boolean getDotPositionOnLeft() {
- return mBadgedImageView.getDotOnLeft();
- }
-
- /**
- * Changes the dot's visibility to match the bubble view's state, running the provided callback
- * after animation if requested.
- */
- private void updateDotVisibility(boolean animate, Runnable after) {
- final boolean showDot = isDotShowing();
- if (animate) {
- animateDot(showDot, after);
- } else {
- mBadgedImageView.setShowDot(showDot);
- mBadgedImageView.setDotScale(showDot ? 1f : 0f);
- }
- }
-
- /**
- * Animates the badge to show or hide.
- */
- private void animateDot(boolean showDot, Runnable after) {
- if (mBadgedImageView.isShowingDot() == showDot) {
- return;
- }
- // Do NOT wait until after animation ends to setShowDot
- // to avoid overriding more recent showDot states.
- mBadgedImageView.setShowDot(showDot);
- mBadgedImageView.clearAnimation();
- mBadgedImageView.animate().setDuration(200)
- .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
- .setUpdateListener((valueAnimator) -> {
- float fraction = valueAnimator.getAnimatedFraction();
- fraction = showDot ? fraction : 1f - fraction;
- mBadgedImageView.setDotScale(fraction);
- }).withEndAction(() -> {
- mBadgedImageView.setDotScale(showDot ? 1f : 0f);
- if (after != null) {
- after.run();
- }
- }).start();
- }
-
- void updateViews() {
- if (mBubble == null || mBubbleIconFactory == null) {
- return;
- }
-
- Drawable bubbleDrawable = getBubbleDrawable(mContext);
- BitmapInfo badgeBitmapInfo = getBadgedBitmap();
- BitmapInfo bubbleBitmapInfo = getBubbleBitmap(bubbleDrawable, badgeBitmapInfo);
- mBadgedImageView.setImageBitmap(bubbleBitmapInfo.icon);
-
- // Update badge.
- mDotColor = ColorUtils.blendARGB(badgeBitmapInfo.color, Color.WHITE, WHITE_SCRIM_ALPHA);
- mBadgedImageView.setDotColor(mDotColor);
-
- // Update dot.
- Path iconPath = PathParser.createPathFromPathData(
- getResources().getString(com.android.internal.R.string.config_icon_mask));
- Matrix matrix = new Matrix();
- float scale = mBubbleIconFactory.getNormalizer().getScale(bubbleDrawable,
- null /* outBounds */, null /* path */, null /* outMaskShape */);
- float radius = BadgedImageView.DEFAULT_PATH_SIZE / 2f;
- matrix.setScale(scale /* x scale */, scale /* y scale */, radius /* pivot x */,
- radius /* pivot y */);
- iconPath.transform(matrix);
- mBadgedImageView.drawDot(iconPath);
-
- animateDot(isDotShowing(), null /* after */);
- }
-
- Drawable getBubbleDrawable(Context context) {
- if (mBubble.getShortcutInfo() != null && mBubble.usingShortcutInfo()) {
- LauncherApps launcherApps =
- (LauncherApps) getContext().getSystemService(Context.LAUNCHER_APPS_SERVICE);
- int density = getContext().getResources().getConfiguration().densityDpi;
- return launcherApps.getShortcutIconDrawable(mBubble.getShortcutInfo(), density);
- } else {
- Notification.BubbleMetadata metadata = getEntry().getBubbleMetadata();
- Icon ic = metadata.getIcon();
- return ic.loadDrawable(context);
- }
- }
-
- BitmapInfo getBadgedBitmap() {
- Bitmap userBadgedBitmap = mBubbleIconFactory.createIconBitmap(
- mBubble.getUserBadgedAppIcon(), 1f, mBubbleIconFactory.getBadgeSize());
-
- Canvas c = new Canvas();
- ShadowGenerator shadowGenerator = new ShadowGenerator(mBubbleIconFactory.getBadgeSize());
- c.setBitmap(userBadgedBitmap);
- shadowGenerator.recreateIcon(Bitmap.createBitmap(userBadgedBitmap), c);
- BitmapInfo bitmapInfo = mBubbleIconFactory.createIconBitmap(userBadgedBitmap);
- return bitmapInfo;
- }
-
- BitmapInfo getBubbleBitmap(Drawable bubble, BitmapInfo badge) {
- BitmapInfo bubbleIconInfo = mBubbleIconFactory.createBadgedIconBitmap(bubble,
- null /* user */,
- true /* shrinkNonAdaptiveIcons */);
-
- mBubbleIconFactory.badgeWithDrawable(bubbleIconInfo.icon,
- new BitmapDrawable(mContext.getResources(), badge.icon));
- return bubbleIconInfo;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 9bd729e..442313d 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -35,7 +35,9 @@
import com.android.systemui.statusbar.notification.people.PeopleHubModule;
import com.android.systemui.statusbar.phone.KeyguardLiftController;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarComponent;
import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.util.concurrency.ConcurrencyModule;
import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.time.SystemClock;
import com.android.systemui.util.time.SystemClockImpl;
@@ -52,7 +54,9 @@
* implementation.
*/
@Module(includes = {AssistModule.class,
- PeopleHubModule.class})
+ ConcurrencyModule.class,
+ PeopleHubModule.class},
+ subcomponents = {StatusBarComponent.class})
public abstract class SystemUIModule {
@Binds
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
index e9265749..e50e0fe 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
@@ -25,7 +25,6 @@
import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.fragments.FragmentService;
-import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.InjectionInflationController;
@@ -73,12 +72,6 @@
Dependency.DependencyInjector createDependency();
/**
- * Injects the StatusBar.
- */
- @Singleton
- StatusBar.StatusBarInjector getStatusBarInjector();
-
- /**
* FragmentCreator generates all Fragments that need injection.
*/
@Singleton
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/Background.java b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/Background.java
new file mode 100644
index 0000000..141c901
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/Background.java
@@ -0,0 +1,30 @@
+/*
+ * 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.dagger.qualifiers;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface Background {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/Main.java b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/Main.java
new file mode 100644
index 0000000..7b09774
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/Main.java
@@ -0,0 +1,30 @@
+/*
+ * 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.dagger.qualifiers;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface Main {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java b/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java
index d2fe394..ea1def0 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java
@@ -28,12 +28,10 @@
* and triaging purposes.
*/
public class DozeEvent extends RichEvent {
- /**
- * Initializes a doze event
- */
- public DozeEvent init(@EventType int type, String reason) {
- super.init(DEBUG, type, reason);
- return this;
+ public static final int TOTAL_EVENT_TYPES = 19;
+
+ public DozeEvent(int logLevel, int type, String reason) {
+ super(logLevel, type, reason);
}
/**
@@ -91,6 +89,21 @@
}
}
+ /**
+ * Builds a DozeEvent.
+ */
+ public static class DozeEventBuilder extends RichEvent.Builder<DozeEventBuilder> {
+ @Override
+ public DozeEventBuilder getBuilder() {
+ return this;
+ }
+
+ @Override
+ public RichEvent build() {
+ return new DozeEvent(mLogLevel, mType, mReason);
+ }
+ }
+
@IntDef({PICKUP_WAKEUP, PULSE_START, PULSE_FINISH, NOTIFICATION_PULSE, DOZING, FLING,
EMERGENCY_CALL, KEYGUARD_BOUNCER_CHANGED, SCREEN_ON, SCREEN_OFF, MISSED_TICK,
TIME_TICK_SCHEDULED, KEYGUARD_VISIBILITY_CHANGE, DOZE_STATE_CHANGED, WAKE_DISPLAY,
@@ -119,7 +132,6 @@
public static final int PULSE_DROPPED = 16;
public static final int PULSE_DISABLED_BY_PROX = 17;
public static final int SENSOR_TRIGGERED = 18;
- public static final int TOTAL_EVENT_TYPES = 19;
public static final int TOTAL_REASONS = 10;
@IntDef({PULSE_REASON_NONE, PULSE_REASON_INTENT, PULSE_REASON_NOTIFICATION,
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index fe50421..2e4466d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -35,11 +35,9 @@
* dependency DumpController DozeLog
*/
@Singleton
-public class DozeLog extends SysuiLog<DozeEvent> {
+public class DozeLog extends SysuiLog {
private static final String TAG = "DozeLog";
- private DozeEvent mRecycledEvent;
-
private boolean mPulsing;
private long mSince;
private SummaryStats mPickupPulseNearVibrationStats;
@@ -75,8 +73,8 @@
* Appends pickup wakeup event to the logs
*/
public void tracePickupWakeUp(boolean withinVibrationThreshold) {
- log(DozeEvent.PICKUP_WAKEUP, "withinVibrationThreshold=" + withinVibrationThreshold);
- if (mEnabled) {
+ if (log(DozeEvent.PICKUP_WAKEUP,
+ "withinVibrationThreshold=" + withinVibrationThreshold)) {
(withinVibrationThreshold ? mPickupPulseNearVibrationStats
: mPickupPulseNotNearVibrationStats).append();
}
@@ -87,24 +85,27 @@
* @param reason why the pulse started
*/
public void tracePulseStart(@DozeEvent.Reason int reason) {
- log(DozeEvent.PULSE_START, DozeEvent.reasonToString(reason));
- if (mEnabled) mPulsing = true;
+ if (log(DozeEvent.PULSE_START, DozeEvent.reasonToString(reason))) {
+ mPulsing = true;
+ }
}
/**
* Appends pulse finished event to the logs
*/
public void tracePulseFinish() {
- log(DozeEvent.PULSE_FINISH);
- if (mEnabled) mPulsing = false;
+ if (log(DozeEvent.PULSE_FINISH)) {
+ mPulsing = false;
+ }
}
/**
* Appends pulse event to the logs
*/
public void traceNotificationPulse() {
- log(DozeEvent.NOTIFICATION_PULSE);
- if (mEnabled) mNotificationPulseStats.append();
+ if (log(DozeEvent.NOTIFICATION_PULSE)) {
+ mNotificationPulseStats.append();
+ }
}
/**
@@ -112,8 +113,9 @@
* @param dozing true if dozing, else false
*/
public void traceDozing(boolean dozing) {
- log(DozeEvent.DOZING, "dozing=" + dozing);
- if (mEnabled) mPulsing = false;
+ if (log(DozeEvent.DOZING, "dozing=" + dozing)) {
+ mPulsing = false;
+ }
}
/**
@@ -131,8 +133,9 @@
* Appends emergency call event to the logs
*/
public void traceEmergencyCall() {
- log(DozeEvent.EMERGENCY_CALL);
- if (mEnabled) mEmergencyCallStats.append();
+ if (log(DozeEvent.EMERGENCY_CALL)) {
+ mEmergencyCallStats.append();
+ }
}
/**
@@ -147,8 +150,7 @@
* Appends screen-on event to the logs
*/
public void traceScreenOn() {
- log(DozeEvent.SCREEN_ON, "pulsing=" + mPulsing);
- if (mEnabled) {
+ if (log(DozeEvent.SCREEN_ON, "pulsing=" + mPulsing)) {
(mPulsing ? mScreenOnPulsingStats : mScreenOnNotPulsingStats).append();
mPulsing = false;
}
@@ -186,8 +188,10 @@
* @param showing whether the keyguard is now showing
*/
public void traceKeyguard(boolean showing) {
- log(DozeEvent.KEYGUARD_VISIBILITY_CHANGE, "showing=" + showing);
- if (mEnabled && !showing) mPulsing = false;
+ if (log(DozeEvent.KEYGUARD_VISIBILITY_CHANGE, "showing=" + showing)
+ && !showing) {
+ mPulsing = false;
+ }
}
/**
@@ -213,11 +217,12 @@
* @param reason why proximity result was triggered
*/
public void traceProximityResult(boolean near, long millis, @DozeEvent.Reason int reason) {
- log(DozeEvent.PROXIMITY_RESULT,
+ if (log(DozeEvent.PROXIMITY_RESULT,
" reason=" + DozeEvent.reasonToString(reason)
- + " near=" + near
- + " millis=" + millis);
- if (mEnabled) mProxStats[reason][near ? 0 : 1].append();
+ + " near=" + near
+ + " millis=" + millis)) {
+ mProxStats[reason][near ? 0 : 1].append();
+ }
}
/**
@@ -245,16 +250,15 @@
}
}
- private void log(@DozeEvent.EventType int eventType) {
- log(eventType, "");
+ private boolean log(@DozeEvent.EventType int eventType) {
+ return log(eventType, "");
}
- private void log(@DozeEvent.EventType int eventType, String msg) {
- if (mRecycledEvent != null) {
- mRecycledEvent = log(mRecycledEvent.init(eventType, msg));
- } else {
- mRecycledEvent = log(new DozeEvent().init(eventType, msg));
- }
+ private boolean log(@DozeEvent.EventType int eventType, String msg) {
+ return super.log(new DozeEvent.DozeEventBuilder()
+ .setType(eventType)
+ .setReason(msg)
+ .build());
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index b5845947..63a7771 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -669,7 +669,10 @@
// Take an "interactive" bugreport.
MetricsLogger.action(mContext,
MetricsEvent.ACTION_BUGREPORT_FROM_POWER_MENU_INTERACTIVE);
- ActivityManager.getService().requestInteractiveBugReport();
+ if (!ActivityManager.getService().launchBugReportHandlerApp()) {
+ Log.w(TAG, "Bugreport handler could not be launched");
+ ActivityManager.getService().requestInteractiveBugReport();
+ }
} catch (RemoteException e) {
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
index 99c55f1..f815b5d 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
@@ -79,12 +79,6 @@
});
}
- private void animate() {
- mAnimator.cancel();
- mAnimator.setFloatValues(mReveal, mAwake ? MAX_REVEAL : MIN_REVEAL);
- mAnimator.start();
- }
-
public float getReveal() {
return mReveal;
}
@@ -93,8 +87,8 @@
if (DEBUG) {
Log.d(TAG, "updateAwake: awake=" + awake + ", duration=" + duration);
}
+ mAnimator.cancel();
mAwake = awake;
- mAnimator.setDuration(duration);
if (duration == 0) {
// We are transiting from home to aod or aod to home directly,
// we don't need to do transition in these cases.
@@ -103,7 +97,9 @@
mRevealListener.onRevealStateChanged();
mRevealListener.onRevealEnd();
} else {
- animate();
+ mAnimator.setDuration(duration);
+ mAnimator.setFloatValues(mReveal, mAwake ? MAX_REVEAL : MIN_REVEAL);
+ mAnimator.start();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/Event.java b/packages/SystemUI/src/com/android/systemui/log/Event.java
index 7bc1abf..92862a2 100644
--- a/packages/SystemUI/src/com/android/systemui/log/Event.java
+++ b/packages/SystemUI/src/com/android/systemui/log/Event.java
@@ -37,28 +37,20 @@
public static final int INFO = 4;
public static final int WARN = 5;
public static final int ERROR = 6;
- public static final @Level int DEFAULT_LOG_LEVEL = DEBUG;
private long mTimestamp;
- private @Level int mLogLevel = DEFAULT_LOG_LEVEL;
- private String mMessage = "";
+ private @Level int mLogLevel = DEBUG;
+ protected String mMessage;
- /**
- * initialize an event with a message
- */
- public Event init(String message) {
- init(DEFAULT_LOG_LEVEL, message);
- return this;
+ public Event(String message) {
+ mTimestamp = System.currentTimeMillis();
+ mMessage = message;
}
- /**
- * initialize an event with a logLevel and message
- */
- public Event init(@Level int logLevel, String message) {
+ public Event(@Level int logLevel, String message) {
mTimestamp = System.currentTimeMillis();
mLogLevel = logLevel;
mMessage = message;
- return this;
}
public String getMessage() {
@@ -72,13 +64,4 @@
public @Level int getLogLevel() {
return mLogLevel;
}
-
- /**
- * Recycle this event
- */
- void recycle() {
- mTimestamp = -1;
- mLogLevel = DEFAULT_LOG_LEVEL;
- mMessage = "";
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/RichEvent.java b/packages/SystemUI/src/com/android/systemui/log/RichEvent.java
index 470f2b0..acf761ed 100644
--- a/packages/SystemUI/src/com/android/systemui/log/RichEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/log/RichEvent.java
@@ -23,21 +23,23 @@
* Events are stored in {@link SysuiLog} and can be printed in a dumpsys.
*/
public abstract class RichEvent extends Event {
- private int mType;
+ private final int mType;
+ private final String mReason;
/**
- * Initializes a rich event that includes an event type that matches with an index in the array
+ * Create a rich event that includes an event type that matches with an index in the array
* getEventLabels().
*/
- public RichEvent init(@Event.Level int logLevel, int type, String reason) {
+ public RichEvent(@Event.Level int logLevel, int type, String reason) {
+ super(logLevel, null);
final int numEvents = getEventLabels().length;
if (type < 0 || type >= numEvents) {
throw new IllegalArgumentException("Unsupported event type. Events only supported"
+ " from 0 to " + (numEvents - 1) + ", but given type=" + type);
}
mType = type;
- super.init(logLevel, getEventLabels()[mType] + " " + reason);
- return this;
+ mReason = reason;
+ mMessage = getEventLabels()[mType] + " " + mReason;
}
/**
@@ -47,43 +49,25 @@
*/
public abstract String[] getEventLabels();
- @Override
- public void recycle() {
- super.recycle();
- mType = -1;
- }
-
public int getType() {
return mType;
}
+ public String getReason() {
+ return mReason;
+ }
+
/**
* Builder to build a RichEvent.
* @param <B> Log specific builder that is extending this builder
- * @param <E> Type of event we'll be building
*/
- public abstract static class Builder<B extends Builder<B, E>, E extends RichEvent> {
+ public abstract static class Builder<B extends Builder<B>> {
public static final int UNINITIALIZED = -1;
- public final SysuiLog mLog;
private B mBuilder = getBuilder();
- protected int mType;
+ protected int mType = UNINITIALIZED;
protected String mReason;
- protected @Level int mLogLevel;
-
- public Builder(SysuiLog sysuiLog) {
- mLog = sysuiLog;
- reset();
- }
-
- /**
- * Reset this builder's parameters so it can be reused to build another RichEvent.
- */
- public void reset() {
- mType = UNINITIALIZED;
- mReason = null;
- mLogLevel = VERBOSE;
- }
+ protected @Level int mLogLevel = VERBOSE;
/**
* Get the log-specific builder.
@@ -91,9 +75,9 @@
public abstract B getBuilder();
/**
- * Build the log-specific event given an event to populate.
+ * Build the log-specific event.
*/
- public abstract E build(E e);
+ public abstract RichEvent build();
/**
* Optional - set the log level. Defaults to DEBUG.
diff --git a/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java b/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java
index e41032a..f094cb9 100644
--- a/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java
@@ -20,7 +20,6 @@
import android.os.SystemProperties;
import android.util.Log;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.DumpController;
import com.android.systemui.Dumpable;
@@ -40,25 +39,22 @@
* To manually view the logs via adb:
* adb shell dumpsys activity service com.android.systemui/.SystemUIService \
* dependency DumpController <SysuiLogId>
- *
- * Logs can be disabled by setting the following SystemProperty and then restarting the device:
- * adb shell setprop persist.sysui.log.enabled.<id> true/false && adb reboot
- *
- * @param <E> Type of event we'll be logging
*/
-public class SysuiLog<E extends Event> implements Dumpable {
+public class SysuiLog implements Dumpable {
public static final SimpleDateFormat DATE_FORMAT =
new SimpleDateFormat("MM-dd HH:mm:ss", Locale.US);
- protected final Object mDataLock = new Object();
+ private final Object mDataLock = new Object();
private final String mId;
private final int mMaxLogs;
- protected boolean mEnabled;
+ private boolean mEnabled;
- @VisibleForTesting protected ArrayDeque<E> mTimeline;
+ @VisibleForTesting protected ArrayDeque<Event> mTimeline;
/**
* Creates a SysuiLog
+ * To enable or disable logs, set the system property and then restart the device:
+ * adb shell setprop sysui.log.enabled.<id> true/false && adb reboot
* @param dumpController where to register this logger's dumpsys
* @param id user-readable tag for this logger
* @param maxDebugLogs maximum number of logs to retain when {@link sDebuggable} is true
@@ -78,20 +74,23 @@
dumpController.registerDumpable(mId, this);
}
+ public SysuiLog(DumpController dumpController, String id) {
+ this(dumpController, id, DEFAULT_MAX_DEBUG_LOGS, DEFAULT_MAX_LOGS);
+ }
+
/**
* Logs an event to the timeline which can be printed by the dumpsys.
* May also log to logcat if enabled.
- * @return the last event that was discarded from the Timeline (can be recycled)
+ * @return true if event was logged, else false
*/
- public E log(E event) {
+ public boolean log(Event event) {
if (!mEnabled) {
- return null;
+ return false;
}
- E recycledEvent = null;
synchronized (mDataLock) {
if (mTimeline.size() >= mMaxLogs) {
- recycledEvent = mTimeline.removeFirst();
+ mTimeline.removeFirst();
}
mTimeline.add(event);
@@ -117,18 +116,13 @@
break;
}
}
-
- if (recycledEvent != null) {
- recycledEvent.recycle();
- }
-
- return recycledEvent;
+ return true;
}
/**
* @return user-readable string of the given event with timestamp
*/
- private String eventToTimestampedString(Event event) {
+ public String eventToTimestampedString(Event event) {
StringBuilder sb = new StringBuilder();
sb.append(SysuiLog.DATE_FORMAT.format(event.getTimestamp()));
sb.append(" ");
@@ -143,7 +137,9 @@
return event.getMessage();
}
- @GuardedBy("mDataLock")
+ /**
+ * only call on this method if you have the mDataLock
+ */
private void dumpTimelineLocked(PrintWriter pw) {
pw.println("\tTimeline:");
@@ -166,7 +162,7 @@
}
private static boolean sDebuggable = Build.IS_DEBUGGABLE;
- private static final String SYSPROP_ENABLED_PREFIX = "persist.sysui.log.enabled.";
+ private static final String SYSPROP_ENABLED_PREFIX = "sysui.log.enabled.";
private static final boolean LOG_TO_LOGCAT_ENABLED = sDebuggable;
private static final boolean DEFAULT_ENABLED = sDebuggable;
private static final int DEFAULT_MAX_DEBUG_LOGS = 100;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index 0a9100f..f30c181 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -25,7 +25,6 @@
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.Build;
-import android.os.Handler;
import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
@@ -34,8 +33,8 @@
import android.widget.Button;
import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.BgHandler;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.State;
import com.android.systemui.qs.QSTileHost;
@@ -47,6 +46,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -55,8 +55,8 @@
private final ArrayList<TileInfo> mTiles = new ArrayList<>();
private final ArraySet<String> mSpecs = new ArraySet<>();
- private final Handler mBgHandler;
- private final Handler mMainHandler;
+ private final Executor mMainExecutor;
+ private final Executor mBgExecutor;
private final Context mContext;
private TileStateListener mListener;
@@ -64,10 +64,10 @@
@Inject
public TileQueryHelper(Context context,
- @MainHandler Handler mainHandler, @BgHandler Handler bgHandler) {
+ @Main Executor mainExecutor, @Background Executor bgExecutor) {
mContext = context;
- mMainHandler = mainHandler;
- mBgHandler = bgHandler;
+ mMainExecutor = mainExecutor;
+ mBgExecutor = bgExecutor;
}
public void setListener(TileStateListener listener) {
@@ -126,7 +126,7 @@
tilesToAdd.add(tile);
}
- mBgHandler.post(() -> {
+ mBgExecutor.execute(() -> {
for (QSTile tile : tilesToAdd) {
final QSTile.State state = tile.getState().copy();
// Ignore the current state and get the generic label instead.
@@ -139,7 +139,7 @@
}
private void addPackageTiles(final QSTileHost host) {
- mBgHandler.post(() -> {
+ mBgExecutor.execute(() -> {
Collection<QSTile> params = host.getTiles();
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> services = pm.queryIntentServicesAsUser(
@@ -185,7 +185,7 @@
private void notifyTilesChanged(final boolean finished) {
final ArrayList<TileInfo> tilesToReturn = new ArrayList<>(mTiles);
- mMainHandler.post(() -> {
+ mMainExecutor.execute(() -> {
if (mListener != null) {
mListener.onTilesChanged(tilesToReturn);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
index fcdd234..f3e2f10 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -162,6 +162,8 @@
if (runningTask.supportsSplitScreenMultiWindow) {
if (ActivityManagerWrapper.getInstance().setTaskWindowingModeSplitScreenPrimary(
runningTask.id, stackCreateMode, initialBounds)) {
+ mDividerOptional.ifPresent(Divider::onDockedTopTask);
+
// The overview service is handling split screen, so just skip the wait for the
// first draw and notify the divider to start animating now
mDividerOptional.ifPresent(Divider::onRecentsDrawn);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index fedd855..5041354 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -804,8 +804,8 @@
List<Notification.Action> actions = smartActionsFuture.get(timeoutMs,
TimeUnit.MILLISECONDS);
long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
- Slog.d(TAG, String.format("Wait time for smart actions: %d ms",
- waitTimeMs));
+ Slog.d(TAG, String.format("Got %d smart actions. Wait time: %d ms",
+ actions.size(), waitTimeMs));
notifyScreenshotOp(screenshotId, smartActionsProvider,
ScreenshotNotificationSmartActionsProvider.ScreenshotOp.WAIT_FOR_SMART_ACTIONS,
ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.SUCCESS,
@@ -813,7 +813,8 @@
return actions;
} catch (Throwable e) {
long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
- Slog.d(TAG, "Failed to obtain screenshot notification smart actions.", e);
+ Slog.e(TAG, String.format("Error getting smart actions. Wait time: %d ms", waitTimeMs),
+ e);
ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus status =
(e instanceof TimeoutException)
? ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.TIMEOUT
@@ -942,14 +943,16 @@
public static class SmartActionsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- PendingIntent actionIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT);
+ PendingIntent pendingIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT);
+ Intent actionIntent = pendingIntent.getIntent();
+ String actionType = intent.getStringExtra(EXTRA_ACTION_TYPE);
+ Slog.d(TAG, "Executing smart action [" + actionType + "]:" + actionIntent);
ActivityOptions opts = ActivityOptions.makeBasic();
- context.startActivityAsUser(actionIntent.getIntent(), opts.toBundle(),
+ context.startActivityAsUser(actionIntent, opts.toBundle(),
UserHandle.CURRENT);
- Slog.d(TAG, "Screenshot notification smart action is invoked.");
notifyScreenshotAction(context, intent.getStringExtra(EXTRA_ID),
- intent.getStringExtra(EXTRA_ACTION_TYPE),
+ actionType,
true);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index d2268e1..76925b4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -456,9 +456,9 @@
SystemUiDeviceConfigFlags
.SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS,
1000);
- List<Notification.Action> smartActions = buildSmartActions(
- GlobalScreenshot.getSmartActions(mScreenshotId, smartActionsFuture,
- timeoutMs, mSmartActionsProvider), context);
+ List<Notification.Action> smartActions = GlobalScreenshot.getSmartActions(mScreenshotId,
+ smartActionsFuture, timeoutMs, mSmartActionsProvider);
+ smartActions = buildSmartActions(smartActions, context);
for (Notification.Action action : smartActions) {
notificationBuilder.addAction(action);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
index 4c4112f..2005d79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
@@ -17,14 +17,13 @@
package com.android.systemui.statusbar;
import android.annotation.NonNull;
-import android.os.Handler;
-import android.os.HandlerExecutor;
import android.provider.DeviceConfig;
import android.util.ArrayMap;
-import com.android.systemui.dagger.qualifiers.BgHandler;
+import com.android.systemui.dagger.qualifiers.Background;
import java.util.Map;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -49,15 +48,15 @@
private final Map<String, Boolean> mCachedDeviceConfigFlags = new ArrayMap<>();
@Inject
- public FeatureFlags(@BgHandler Handler bgHandler) {
+ public FeatureFlags(@Background Executor executor) {
DeviceConfig.addOnPropertiesChangedListener(
"systemui",
- new HandlerExecutor(bgHandler),
+ executor,
this::onPropertiesChanged);
}
public boolean isNewNotifPipelineEnabled() {
- return getDeviceConfigFlag("notification.newpipeline.enabled", true);
+ return getDeviceConfigFlag("notification.newpipeline.enabled", false);
}
private void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
index 9f5cf68..61043fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
@@ -36,6 +36,7 @@
import com.android.systemui.Dependency;
import com.android.systemui.assist.AssistHandleViewController;
import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
import com.android.systemui.statusbar.phone.AutoHideController;
@@ -168,6 +169,9 @@
View navigationWindow = navBar.getView().getRootView();
WindowManagerGlobal.getInstance()
.removeView(navigationWindow, true /* immediate */);
+ // Also remove FragmentHostState here in case that onViewDetachedFromWindow has not yet
+ // invoked after display removal.
+ FragmentHostManager.removeAndDestroy(navigationWindow);
mNavigationBars.remove(displayId);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index a98f826..d3a9c2c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -62,6 +62,7 @@
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ScrimState;
import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -122,6 +123,7 @@
private final Context mContext;
private final MediaSessionManager mMediaSessionManager;
private final ArrayList<MediaListener> mMediaListeners;
+ private final Lazy<StatusBar> mStatusBarLazy;
private final MediaArtworkProcessor mMediaArtworkProcessor;
private final Set<AsyncTask<?, ?, ?>> mProcessArtworkTasks = new ArraySet<>();
@@ -182,6 +184,7 @@
public NotificationMediaManager(
Context context,
Lazy<ShadeController> shadeController,
+ Lazy<StatusBar> statusBarLazy,
Lazy<StatusBarWindowController> statusBarWindowController,
NotificationEntryManager notificationEntryManager,
MediaArtworkProcessor mediaArtworkProcessor,
@@ -195,6 +198,8 @@
// TODO: use MediaSessionManager.SessionListener to hook us up to future updates
// in session state
mShadeController = shadeController;
+ // TODO: use KeyguardStateController#isOccluded to remove this dependency
+ mStatusBarLazy = statusBarLazy;
mStatusBarWindowController = statusBarWindowController;
mEntryManager = notificationEntryManager;
notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@@ -526,9 +531,8 @@
}
}
- ShadeController shadeController = mShadeController.get();
StatusBarWindowController windowController = mStatusBarWindowController.get();
- boolean hideBecauseOccluded = shadeController != null && shadeController.isOccluded();
+ boolean hideBecauseOccluded = mStatusBarLazy.get().isOccluded();
final boolean hasArtwork = artworkDrawable != null;
mColorExtractor.setHasMediaArtwork(hasMediaArtwork);
@@ -599,6 +603,7 @@
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
}
+ ShadeController shadeController = mShadeController.get();
boolean cannotAnimateDoze = shadeController != null
&& shadeController.isDozing()
&& !ScrimState.AOD.getAnimateChange();
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 d81743a..7a58097 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -267,13 +267,14 @@
NotificationEntry entry = mPendingNotifications.get(key);
entry.abortTask();
mPendingNotifications.remove(key);
- mNotifLog.log(NotifEvent.INFLATION_ABORTED, entry, "PendingNotification aborted"
- + " reason=" + reason);
+ mNotifLog.log(NotifEvent.INFLATION_ABORTED, entry.getSbn(), null,
+ "PendingNotification aborted. " + reason);
}
NotificationEntry addedEntry = getActiveNotificationUnfiltered(key);
if (addedEntry != null) {
addedEntry.abortTask();
- mNotifLog.log(NotifEvent.INFLATION_ABORTED, addedEntry.getKey() + " " + reason);
+ mNotifLog.log(NotifEvent.INFLATION_ABORTED, addedEntry.getSbn(),
+ null, reason);
}
}
@@ -500,7 +501,7 @@
abortExistingInflation(key, "addNotification");
mPendingNotifications.put(key, entry);
- mNotifLog.log(NotifEvent.NOTIF_ADDED, entry);
+ mNotifLog.log(NotifEvent.NOTIF_ADDED, entry.getSbn());
for (NotificationEntryListener listener : mNotificationEntryListeners) {
listener.onPendingEntryAdded(entry);
}
@@ -535,7 +536,7 @@
entry.setSbn(notification);
mGroupManager.onEntryUpdated(entry, oldSbn);
- mNotifLog.log(NotifEvent.NOTIF_UPDATED, entry);
+ mNotifLog.log(NotifEvent.NOTIF_UPDATED, entry.getSbn(), entry.getRanking());
for (NotificationEntryListener listener : mNotificationEntryListeners) {
listener.onPreEntryUpdated(entry);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
index 3f7fd1a..7b1dc07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
@@ -64,6 +64,8 @@
}
};
+ // TODO: (b/145659174) remove after moving to NewNotifPipeline. Replaced by
+ // DeviceProvisionedCoordinator
private final DeviceProvisionedListener mDeviceProvisionedListener =
new DeviceProvisionedListener() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImpl.java
index a1cfb54..21a4b4f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImpl.java
@@ -29,6 +29,7 @@
import android.annotation.MainThread;
import android.annotation.Nullable;
import android.util.ArrayMap;
+import android.util.Log;
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener;
@@ -39,8 +40,6 @@
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.SectionsProvider;
-import com.android.systemui.statusbar.notification.logging.NotifEvent;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.util.Assert;
import com.android.systemui.util.time.SystemClock;
@@ -60,8 +59,8 @@
@MainThread
@Singleton
public class NotifListBuilderImpl implements NotifListBuilder {
+
private final SystemClock mSystemClock;
- private final NotifLog mNotifLog;
private final List<ListEntry> mNotifList = new ArrayList<>();
@@ -87,10 +86,9 @@
private final List<ListEntry> mReadOnlyNotifList = Collections.unmodifiableList(mNotifList);
@Inject
- public NotifListBuilderImpl(SystemClock systemClock, NotifLog notifLog) {
+ public NotifListBuilderImpl(SystemClock systemClock) {
Assert.isMainThread();
mSystemClock = systemClock;
- mNotifLog = notifLog;
}
/**
@@ -195,8 +193,7 @@
Assert.isMainThread();
mPipelineState.requireIsBefore(STATE_BUILD_STARTED);
- mNotifLog.log(NotifEvent.ON_BUILD_LIST, "Request received from "
- + "NotifCollection");
+ Log.i(TAG, "Build request received from NotifCollection");
mAllEntries = entries;
buildList();
}
@@ -205,7 +202,8 @@
private void onFilterInvalidated(NotifFilter filter) {
Assert.isMainThread();
- mNotifLog.log(NotifEvent.FILTER_INVALIDATED, String.format(
+ // TODO: Convert these log statements (here and elsewhere) into timeline logging
+ Log.i(TAG, String.format(
"Filter \"%s\" invalidated; pipeline state is %d",
filter.getName(),
mPipelineState.getState()));
@@ -216,7 +214,7 @@
private void onPromoterInvalidated(NotifPromoter filter) {
Assert.isMainThread();
- mNotifLog.log(NotifEvent.PROMOTER_INVALIDATED, String.format(
+ Log.i(TAG, String.format(
"NotifPromoter \"%s\" invalidated; pipeline state is %d",
filter.getName(),
mPipelineState.getState()));
@@ -227,7 +225,7 @@
private void onSectionsProviderInvalidated(SectionsProvider provider) {
Assert.isMainThread();
- mNotifLog.log(NotifEvent.SECTIONS_PROVIDER_INVALIDATED, String.format(
+ Log.i(TAG, String.format(
"Sections provider \"%s\" invalidated; pipeline state is %d",
provider.getName(),
mPipelineState.getState()));
@@ -238,7 +236,7 @@
private void onNotifComparatorInvalidated(NotifComparator comparator) {
Assert.isMainThread();
- mNotifLog.log(NotifEvent.COMPARATOR_INVALIDATED, String.format(
+ Log.i(TAG, String.format(
"Comparator \"%s\" invalidated; pipeline state is %d",
comparator.getName(),
mPipelineState.getState()));
@@ -256,7 +254,7 @@
* if we detect that behavior, we should crash instantly.
*/
private void buildList() {
- mNotifLog.log(NotifEvent.START_BUILD_LIST, "Run #" + mIterationCount + "...");
+ Log.i(TAG, "Starting notif list build #" + mIterationCount + "...");
mPipelineState.requireIsBefore(STATE_BUILD_STARTED);
mPipelineState.setState(STATE_BUILD_STARTED);
@@ -290,16 +288,15 @@
freeEmptyGroups();
// Step 5: Dispatch the new list, first to any listeners and then to the view layer
- mNotifLog.log(NotifEvent.DISPATCH_FINAL_LIST, "List finalized, is:\n"
- + dumpList(mNotifList));
+ Log.i(TAG, "List finalized, is:\n" + dumpList(mNotifList));
+ Log.i(TAG, "Dispatching final list to listeners...");
dispatchOnBeforeRenderList(mReadOnlyNotifList);
if (mOnRenderListListener != null) {
mOnRenderListListener.onRenderList(mReadOnlyNotifList);
}
// Step 6: We're done!
- mNotifLog.log(NotifEvent.LIST_BUILD_COMPLETE,
- "Notif list build #" + mIterationCount + " completed");
+ Log.i(TAG, "Notif list build #" + mIterationCount + " completed");
mPipelineState.setState(STATE_IDLE);
mIterationCount++;
}
@@ -357,7 +354,7 @@
if (existingSummary == null) {
group.setSummary(entry);
} else {
- mNotifLog.log(NotifEvent.WARN, String.format(
+ Log.w(TAG, String.format(
"Duplicate summary for group '%s': '%s' vs. '%s'",
group.getKey(),
existingSummary.getKey(),
@@ -380,8 +377,7 @@
final String topLevelKey = entry.getKey();
if (mGroups.containsKey(topLevelKey)) {
- mNotifLog.log(NotifEvent.WARN,
- "Duplicate non-group top-level key: " + topLevelKey);
+ Log.wtf(TAG, "Duplicate non-group top-level key: " + topLevelKey);
} else {
entry.setParent(ROOT_ENTRY);
out.add(entry);
@@ -543,7 +539,7 @@
private void logParentingChanges() {
for (NotificationEntry entry : mAllEntries) {
if (entry.getParent() != entry.getPreviousParent()) {
- mNotifLog.log(NotifEvent.PARENT_CHANGED, String.format(
+ Log.i(TAG, String.format(
"%s: parent changed from %s to %s",
entry.getKey(),
entry.getPreviousParent() == null
@@ -554,7 +550,7 @@
}
for (GroupEntry group : mGroups.values()) {
if (group.getParent() != group.getPreviousParent()) {
- mNotifLog.log(NotifEvent.PARENT_CHANGED, String.format(
+ Log.i(TAG, String.format(
"%s: parent changed from %s to %s",
group.getKey(),
group.getPreviousParent() == null
@@ -611,17 +607,17 @@
if (filter != entry.mExcludingFilter) {
if (entry.mExcludingFilter == null) {
- mNotifLog.log(NotifEvent.FILTER_CHANGED, String.format(
+ Log.i(TAG, String.format(
"%s: filtered out by '%s'",
entry.getKey(),
filter.getName()));
} else if (filter == null) {
- mNotifLog.log(NotifEvent.FILTER_CHANGED, String.format(
+ Log.i(TAG, String.format(
"%s: no longer filtered out (previous filter was '%s')",
entry.getKey(),
entry.mExcludingFilter.getName()));
} else {
- mNotifLog.log(NotifEvent.FILTER_CHANGED, String.format(
+ Log.i(TAG, String.format(
"%s: filter changed: '%s' -> '%s'",
entry.getKey(),
entry.mExcludingFilter,
@@ -652,22 +648,23 @@
if (promoter != entry.mNotifPromoter) {
if (entry.mNotifPromoter == null) {
- mNotifLog.log(NotifEvent.PROMOTER_CHANGED, String.format(
+ Log.i(TAG, String.format(
"%s: Entry promoted to top level by '%s'",
entry.getKey(),
promoter.getName()));
} else if (promoter == null) {
- mNotifLog.log(NotifEvent.PROMOTER_CHANGED, String.format(
+ Log.i(TAG, String.format(
"%s: Entry is no longer promoted to top level (previous promoter was '%s')",
entry.getKey(),
entry.mNotifPromoter.getName()));
} else {
- mNotifLog.log(NotifEvent.PROMOTER_CHANGED, String.format(
+ Log.i(TAG, String.format(
"%s: Top-level promoter changed: '%s' -> '%s'",
entry.getKey(),
entry.mNotifPromoter,
promoter));
}
+
entry.mNotifPromoter = promoter;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
index 8bce528..48a4882 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
@@ -16,36 +16,28 @@
package com.android.systemui.statusbar.notification.collection
-import android.app.Notification
import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_HIGH
import android.app.NotificationManager.IMPORTANCE_LOW
import android.app.NotificationManager.IMPORTANCE_MIN
-import android.app.Person
import android.service.notification.NotificationListenerService.Ranking
import android.service.notification.NotificationListenerService.RankingMap
import android.service.notification.StatusBarNotification
import com.android.internal.annotations.VisibleForTesting
-
import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.statusbar.notification.NotificationFilter
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.logging.NotifEvent
import com.android.systemui.statusbar.notification.logging.NotifLog
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT
import com.android.systemui.statusbar.phone.NotificationGroupManager
import com.android.systemui.statusbar.policy.HeadsUpManager
-
-import java.util.Objects
-import java.util.ArrayList
-
-import javax.inject.Inject
-
-import kotlin.Comparator
-
import dagger.Lazy
+import java.util.Objects
+import javax.inject.Inject
private const val TAG = "NotifRankingManager"
@@ -64,7 +56,8 @@
private val headsUpManager: HeadsUpManager,
private val notifFilter: NotificationFilter,
private val notifLog: NotifLog,
- sectionsFeatureManager: NotificationSectionsFeatureManager
+ sectionsFeatureManager: NotificationSectionsFeatureManager,
+ private val peopleNotificationIdentifier: PeopleNotificationIdentifier
) {
var rankingMap: RankingMap? = null
@@ -79,6 +72,9 @@
val aRank = a.ranking.rank
val bRank = b.ranking.rank
+ val aIsPeople = a.isPeopleNotification()
+ val bIsPeople = b.isPeopleNotification()
+
val aMedia = isImportantMedia(a)
val bMedia = isImportantMedia(b)
@@ -88,25 +84,19 @@
val aHeadsUp = a.isRowHeadsUp
val bHeadsUp = b.isRowHeadsUp
- if (usePeopleFiltering && a.isPeopleNotification() != b.isPeopleNotification()) {
- if (a.isPeopleNotification()) -1 else 1
- } else if (aHeadsUp != bHeadsUp) {
- if (aHeadsUp) -1 else 1
- } else if (aHeadsUp) {
+ when {
+ usePeopleFiltering && aIsPeople != bIsPeople -> if (aIsPeople) -1 else 1
+ aHeadsUp != bHeadsUp -> if (aHeadsUp) -1 else 1
// Provide consistent ranking with headsUpManager
- headsUpManager.compare(a, b)
- } else if (aMedia != bMedia) {
+ aHeadsUp -> headsUpManager.compare(a, b)
// Upsort current media notification.
- if (aMedia) -1 else 1
- } else if (aSystemMax != bSystemMax) {
+ aMedia != bMedia -> if (aMedia) -1 else 1
// Upsort PRIORITY_MAX system notifications
- if (aSystemMax) -1 else 1
- } else if (a.isHighPriority != b.isHighPriority) {
- -1 * java.lang.Boolean.compare(a.isHighPriority, b.isHighPriority)
- } else if (aRank != bRank) {
- aRank - bRank
- } else {
- nb.notification.`when`.compareTo(na.notification.`when`)
+ aSystemMax != bSystemMax -> if (aSystemMax) -1 else 1
+ a.isHighPriority != b.isHighPriority ->
+ -1 * a.isHighPriority.compareTo(b.isHighPriority)
+ aRank != bRank -> aRank - bRank
+ else -> nb.notification.`when`.compareTo(na.notification.`when`)
}
}
@@ -138,10 +128,9 @@
val c = entry.channel
val n = entry.sbn.notification
- if (((n.isForegroundService && entry.ranking.importance >= IMPORTANCE_LOW) ||
- n.hasMediaSession() ||
- n.hasPerson() ||
- n.hasStyle(Notification.MessagingStyle::class.java))) {
+ if ((n.isForegroundService && entry.ranking.importance >= IMPORTANCE_LOW) ||
+ n.hasMediaSession() ||
+ entry.isPeopleNotification()) {
// Users who have long pressed and demoted to silent should not see the notification
// in the top section
if (c != null && c.hasUserSetImportance()) {
@@ -204,7 +193,7 @@
isMedia: Boolean,
isSystemMax: Boolean
) {
- if (usePeopleFiltering && entry.hasAssociatedPeople()) {
+ if (usePeopleFiltering && entry.isPeopleNotification()) {
entry.bucket = BUCKET_PEOPLE
} else if (isHeadsUp || isMedia || isSystemMax || entry.isHighPriority) {
entry.bucket = BUCKET_ALERTING
@@ -235,6 +224,11 @@
}
}
}
+
+ private fun NotificationEntry.isPeopleNotification() =
+ sbn.isPeopleNotification()
+ private fun StatusBarNotification.isPeopleNotification() =
+ peopleNotificationIdentifier.isPeopleNotification(this)
}
// Convenience functions
@@ -245,16 +239,3 @@
private fun StatusBarNotification.isSystemNotification(): Boolean {
return "android" == packageName || "com.android.systemui" == packageName
}
-
-private fun Notification.hasPerson(): Boolean {
- val people: ArrayList<Person> =
- (extras?.getParcelableArrayList(Notification.EXTRA_PEOPLE_LIST)) ?: ArrayList()
- return people.isNotEmpty()
-}
-
-private fun Notification.hasStyle(targetStyleClass: Class<*>): Boolean {
- return targetStyleClass == notificationStyle
-}
-
-private fun NotificationEntry.isPeopleNotification(): Boolean =
- sbn.notification.hasStyle(Notification.MessagingStyle::class.java)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
index f5ed089..6daf3fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
@@ -32,6 +32,7 @@
import androidx.annotation.MainThread;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -165,6 +166,7 @@
private void setupInvalidateNotifListCallbacks() {
// register onKeyguardShowing callback
mKeyguardStateController.addCallback(mKeyguardCallback);
+ mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
// register lockscreen settings changed callbacks:
final ContentObserver settingsObserver = new ContentObserver(mMainHandler) {
@@ -230,4 +232,13 @@
invalidateListFromFilter("onStatusBarStateChanged");
}
};
+
+ private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onStrongAuthStateChanged(int userId) {
+ // maybe lockdown mode changed
+ invalidateListFromFilter("onStrongAuthStateChanged");
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifEvent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifEvent.java
index 3b06220..8ebbca2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifEvent.java
@@ -17,12 +17,10 @@
package com.android.systemui.statusbar.notification.logging;
import android.annotation.IntDef;
-import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
import com.android.systemui.log.RichEvent;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.listbuilder.NotifListBuilder;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -33,71 +31,103 @@
* here to mitigate memory usage.
*/
public class NotifEvent extends RichEvent {
+ public static final int TOTAL_EVENT_TYPES = 11;
+
/**
- * Initializes a rich event that includes an event type that matches with an index in the array
- * getEventLabels().
+ * Creates a NotifEvent with an event type that matches with an index in the array
+ * getSupportedEvents() and {@link EventType}.
+ *
+ * The status bar notification and ranking objects are stored as shallow copies of the current
+ * state of the event when this event occurred.
*/
- public NotifEvent init(@EventType int type, StatusBarNotification sbn,
- NotificationListenerService.Ranking ranking, String reason) {
- StringBuilder extraInfo = new StringBuilder(reason);
+ public NotifEvent(int logLevel, int type, String reason, StatusBarNotification sbn,
+ Ranking ranking) {
+ super(logLevel, type, reason);
+ mMessage += getExtraInfo(sbn, ranking);
+ }
+
+ private String getExtraInfo(StatusBarNotification sbn, Ranking ranking) {
+ StringBuilder extraInfo = new StringBuilder();
+
if (sbn != null) {
- extraInfo.append(" " + sbn.getKey());
+ extraInfo.append(" Sbn=");
+ extraInfo.append(sbn);
}
if (ranking != null) {
extraInfo.append(" Ranking=");
- extraInfo.append(ranking.getRank());
+ extraInfo.append(ranking);
}
- super.init(INFO, type, extraInfo.toString());
- return this;
+
+ return extraInfo.toString();
}
/**
- * Event labels for ListBuilderEvents
- * Index corresponds to an # in {@link EventType}
+ * Event labels for NotifEvents
+ * Index corresponds to the {@link EventType}
*/
@Override
public String[] getEventLabels() {
- assert (TOTAL_EVENT_LABELS == (TOTAL_NEM_EVENT_TYPES + TOTAL_LIST_BUILDER_EVENT_TYPES));
- return EVENT_LABELS;
+ final String[] events = new String[]{
+ "NotifAdded",
+ "NotifRemoved",
+ "NotifUpdated",
+ "Filter",
+ "Sort",
+ "FilterAndSort",
+ "NotifVisibilityChanged",
+ "LifetimeExtended",
+ "RemoveIntercepted",
+ "InflationAborted",
+ "Inflated"
+ };
+
+ if (events.length != TOTAL_EVENT_TYPES) {
+ throw new IllegalStateException("NotifEvents events.length should match "
+ + TOTAL_EVENT_TYPES
+ + " events.length=" + events.length
+ + " TOTAL_EVENT_LENGTH=" + TOTAL_EVENT_TYPES);
+ }
+ return events;
}
/**
- * @return if this event occurred in {@link NotifListBuilder}
+ * Builds a NotifEvent.
*/
- static boolean isListBuilderEvent(@EventType int type) {
- return isBetweenInclusive(type, 0, TOTAL_LIST_BUILDER_EVENT_TYPES);
+ public static class NotifEventBuilder extends RichEvent.Builder<NotifEventBuilder> {
+ private StatusBarNotification mSbn;
+ private Ranking mRanking;
+
+ @Override
+ public NotifEventBuilder getBuilder() {
+ return this;
+ }
+
+ /**
+ * Stores the status bar notification object. A shallow copy is stored in the NotifEvent's
+ * constructor.
+ */
+ public NotifEventBuilder setSbn(StatusBarNotification sbn) {
+ mSbn = sbn;
+ return this;
+ }
+
+ /**
+ * Stores the ranking object. A shallow copy is stored in the NotifEvent's
+ * constructor.
+ */
+ public NotifEventBuilder setRanking(Ranking ranking) {
+ mRanking = ranking;
+ return this;
+ }
+
+ @Override
+ public RichEvent build() {
+ return new NotifEvent(mLogLevel, mType, mReason, mSbn, mRanking);
+ }
}
- /**
- * @return if this event occurred in {@link NotificationEntryManager}
- */
- static boolean isNemEvent(@EventType int type) {
- return isBetweenInclusive(type, TOTAL_LIST_BUILDER_EVENT_TYPES,
- TOTAL_LIST_BUILDER_EVENT_TYPES + TOTAL_NEM_EVENT_TYPES);
- }
-
- private static boolean isBetweenInclusive(int x, int a, int b) {
- return x >= a && x <= b;
- }
-
- @IntDef({
- // NotifListBuilder events:
- WARN,
- ON_BUILD_LIST,
- START_BUILD_LIST,
- DISPATCH_FINAL_LIST,
- LIST_BUILD_COMPLETE,
- FILTER_INVALIDATED,
- PROMOTER_INVALIDATED,
- SECTIONS_PROVIDER_INVALIDATED,
- COMPARATOR_INVALIDATED,
- PARENT_CHANGED,
- FILTER_CHANGED,
- PROMOTER_CHANGED,
-
- // NotificationEntryManager events:
- NOTIF_ADDED,
+ @IntDef({NOTIF_ADDED,
NOTIF_REMOVED,
NOTIF_UPDATED,
FILTER,
@@ -109,72 +139,22 @@
INFLATION_ABORTED,
INFLATED
})
+
+ /**
+ * Types of NotifEvents
+ */
@Retention(RetentionPolicy.SOURCE)
public @interface EventType {}
-
- private static final String[] EVENT_LABELS =
- new String[]{
- // NotifListBuilder labels:
- "Warning",
- "OnBuildList",
- "StartBuildList",
- "DispatchFinalList",
- "ListBuildComplete",
- "FilterInvalidated",
- "PromoterInvalidated",
- "SectionsProviderInvalidated",
- "ComparatorInvalidated",
- "ParentChanged",
- "FilterChanged",
- "PromoterChanged",
-
- // NEM event labels:
- "NotifAdded",
- "NotifRemoved",
- "NotifUpdated",
- "Filter",
- "Sort",
- "FilterAndSort",
- "NotifVisibilityChanged",
- "LifetimeExtended",
- "RemoveIntercepted",
- "InflationAborted",
- "Inflated"
- };
-
- private static final int TOTAL_EVENT_LABELS = EVENT_LABELS.length;
-
- /**
- * Events related to {@link NotifListBuilder}
- */
- public static final int WARN = 0;
- public static final int ON_BUILD_LIST = 1;
- public static final int START_BUILD_LIST = 2;
- public static final int DISPATCH_FINAL_LIST = 3;
- public static final int LIST_BUILD_COMPLETE = 4;
- public static final int FILTER_INVALIDATED = 5;
- public static final int PROMOTER_INVALIDATED = 6;
- public static final int SECTIONS_PROVIDER_INVALIDATED = 7;
- public static final int COMPARATOR_INVALIDATED = 8;
- public static final int PARENT_CHANGED = 9;
- public static final int FILTER_CHANGED = 10;
- public static final int PROMOTER_CHANGED = 11;
- private static final int TOTAL_LIST_BUILDER_EVENT_TYPES = 12;
-
- /**
- * Events related to {@link NotificationEntryManager}
- */
- public static final int NOTIF_ADDED = TOTAL_LIST_BUILDER_EVENT_TYPES + 0;
- public static final int NOTIF_REMOVED = TOTAL_LIST_BUILDER_EVENT_TYPES + 1;
- public static final int NOTIF_UPDATED = TOTAL_LIST_BUILDER_EVENT_TYPES + 2;
- public static final int FILTER = TOTAL_LIST_BUILDER_EVENT_TYPES + 3;
- public static final int SORT = TOTAL_LIST_BUILDER_EVENT_TYPES + 4;
- public static final int FILTER_AND_SORT = TOTAL_LIST_BUILDER_EVENT_TYPES + 5;
- public static final int NOTIF_VISIBILITY_CHANGED = TOTAL_LIST_BUILDER_EVENT_TYPES + 6;
- public static final int LIFETIME_EXTENDED = TOTAL_LIST_BUILDER_EVENT_TYPES + 7;
+ public static final int NOTIF_ADDED = 0;
+ public static final int NOTIF_REMOVED = 1;
+ public static final int NOTIF_UPDATED = 2;
+ public static final int FILTER = 3;
+ public static final int SORT = 4;
+ public static final int FILTER_AND_SORT = 5;
+ public static final int NOTIF_VISIBILITY_CHANGED = 6;
+ public static final int LIFETIME_EXTENDED = 7;
// unable to remove notif - removal intercepted by {@link NotificationRemoveInterceptor}
- public static final int REMOVE_INTERCEPTED = TOTAL_LIST_BUILDER_EVENT_TYPES + 8;
- public static final int INFLATION_ABORTED = TOTAL_LIST_BUILDER_EVENT_TYPES + 9;
- public static final int INFLATED = TOTAL_LIST_BUILDER_EVENT_TYPES + 10;
- private static final int TOTAL_NEM_EVENT_TYPES = 11;
+ public static final int REMOVE_INTERCEPTED = 8;
+ public static final int INFLATION_ABORTED = 9;
+ public static final int INFLATED = 10;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifLog.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifLog.java
index 299d628..1292831 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifLog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifLog.java
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.notification.logging;
-import android.os.SystemProperties;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
@@ -34,82 +33,93 @@
* dependency DumpController NotifLog
*/
@Singleton
-public class NotifLog extends SysuiLog<NotifEvent> {
+public class NotifLog extends SysuiLog {
private static final String TAG = "NotifLog";
- private static final boolean SHOW_NEM_LOGS =
- SystemProperties.getBoolean("persist.sysui.log.notif.nem", true);
- private static final boolean SHOW_LIST_BUILDER_LOGS =
- SystemProperties.getBoolean("persist.sysui.log.notif.listbuilder", true);
-
private static final int MAX_DOZE_DEBUG_LOGS = 400;
private static final int MAX_DOZE_LOGS = 50;
- private NotifEvent mRecycledEvent;
-
@Inject
public NotifLog(DumpController dumpController) {
super(dumpController, TAG, MAX_DOZE_DEBUG_LOGS, MAX_DOZE_LOGS);
}
/**
- * Logs a {@link NotifEvent} with a notification, ranking and message.
- * Uses the last recycled event if available.
+ * Logs a {@link NotifEvent} with a notification, ranking and message
* @return true if successfully logged, else false
*/
- public void log(@NotifEvent.EventType int eventType,
- StatusBarNotification sbn, Ranking ranking, String msg) {
- if (!mEnabled
- || (NotifEvent.isListBuilderEvent(eventType) && !SHOW_LIST_BUILDER_LOGS)
- || (NotifEvent.isNemEvent(eventType) && !SHOW_NEM_LOGS)) {
- return;
- }
-
- if (mRecycledEvent != null) {
- mRecycledEvent = log(mRecycledEvent.init(eventType, sbn, ranking, msg));
- } else {
- mRecycledEvent = log(new NotifEvent().init(eventType, sbn, ranking, msg));
- }
+ public boolean log(@NotifEvent.EventType int eventType, StatusBarNotification sbn,
+ Ranking ranking, String msg) {
+ return log(new NotifEvent.NotifEventBuilder()
+ .setType(eventType)
+ .setSbn(sbn)
+ .setRanking(ranking)
+ .setReason(msg)
+ .build());
}
/**
- * Logs a {@link NotifEvent} with no extra information aside from the event type
+ * Logs a {@link NotifEvent}
+ * @return true if successfully logged, else false
*/
- public void log(@NotifEvent.EventType int eventType) {
- log(eventType, null, null, "");
+ public boolean log(@NotifEvent.EventType int eventType) {
+ return log(eventType, null, null, null);
}
/**
* Logs a {@link NotifEvent} with a message
+ * @return true if successfully logged, else false
*/
- public void log(@NotifEvent.EventType int eventType, String msg) {
- log(eventType, null, null, msg);
+ public boolean log(@NotifEvent.EventType int eventType, String msg) {
+ return log(eventType, null, null, msg);
}
/**
- * Logs a {@link NotifEvent} with a entry
+ * Logs a {@link NotifEvent} with a notification
+ * @return true if successfully logged, else false
*/
- public void log(@NotifEvent.EventType int eventType, NotificationEntry entry) {
- log(eventType, entry.getSbn(), entry.getRanking(), "");
+ public boolean log(@NotifEvent.EventType int eventType, StatusBarNotification sbn) {
+ return log(eventType, sbn, null, "");
}
/**
- * Logs a {@link NotifEvent} with a NotificationEntry and message
+ * Logs a {@link NotifEvent} with a notification
+ * @return true if successfully logged, else false
*/
- public void log(@NotifEvent.EventType int eventType, NotificationEntry entry, String msg) {
- log(eventType, entry.getSbn(), entry.getRanking(), msg);
+ public boolean log(@NotifEvent.EventType int eventType, StatusBarNotification sbn, String msg) {
+ return log(eventType, sbn, null, msg);
}
/**
- * Logs a {@link NotifEvent} with a notification and message
+ * Logs a {@link NotifEvent} with a ranking
+ * @return true if successfully logged, else false
*/
- public void log(@NotifEvent.EventType int eventType, StatusBarNotification sbn, String msg) {
- log(eventType, sbn, null, msg);
+ public boolean log(@NotifEvent.EventType int eventType, Ranking ranking) {
+ return log(eventType, null, ranking, "");
}
/**
- * Logs a {@link NotifEvent} with a ranking and message
+ * Logs a {@link NotifEvent} with a notification and ranking
+ * @return true if successfully logged, else false
*/
- public void log(@NotifEvent.EventType int eventType, Ranking ranking, String msg) {
- log(eventType, null, ranking, msg);
+ public boolean log(@NotifEvent.EventType int eventType, StatusBarNotification sbn,
+ Ranking ranking) {
+ return log(eventType, sbn, ranking, "");
+ }
+
+ /**
+ * Logs a {@link NotifEvent} with a notification entry
+ * @return true if successfully logged, else false
+ */
+ public boolean log(@NotifEvent.EventType int eventType, NotificationEntry entry) {
+ return log(eventType, entry.getSbn(), entry.getRanking(), "");
+ }
+
+ /**
+ * Logs a {@link NotifEvent} with a notification entry
+ * @return true if successfully logged, else false
+ */
+ public boolean log(@NotifEvent.EventType int eventType, NotificationEntry entry,
+ String msg) {
+ return log(eventType, entry.getSbn(), entry.getRanking(), msg);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
index fdd51e9e..8e9a051e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
@@ -318,7 +318,7 @@
}
mParent.addView(mPeopleHubView, targetIndex);
return true;
- } else if (currentHubIndex != targetIndex - 1) {
+ } else if (currentHubIndex != targetIndex) {
if (currentHubIndex < targetIndex) {
targetIndex--;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index 063ad85..09ebb64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -88,10 +88,9 @@
private final PulseExpansionHandler mPulseExpansionHandler;
private final StatusBarWindowController mStatusBarWindowController;
private final NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
- private final StatusBarWindowViewController mStatusBarWindowViewController;
+ private StatusBarWindowViewController mStatusBarWindowViewController;
private final LockscreenLockIconController mLockscreenLockIconController;
private NotificationIconAreaController mNotificationIconAreaController;
- private StatusBarWindowView mStatusBarWindow;
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private NotificationPanelView mNotificationPanel;
private View mAmbientIndicationContainer;
@@ -112,7 +111,6 @@
PulseExpansionHandler pulseExpansionHandler,
StatusBarWindowController statusBarWindowController,
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
- StatusBarWindowViewController statusBarWindowViewController,
LockscreenLockIconController lockscreenLockIconController) {
super();
mDozeLog = dozeLog;
@@ -132,7 +130,6 @@
mPulseExpansionHandler = pulseExpansionHandler;
mStatusBarWindowController = statusBarWindowController;
mNotificationWakeUpCoordinator = notificationWakeUpCoordinator;
- mStatusBarWindowViewController = statusBarWindowViewController;
mLockscreenLockIconController = lockscreenLockIconController;
}
@@ -143,14 +140,14 @@
*/
public void initialize(StatusBar statusBar,
NotificationIconAreaController notificationIconAreaController,
- StatusBarWindowView statusBarWindow,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+ StatusBarWindowViewController statusBarWindowViewController,
NotificationPanelView notificationPanel, View ambientIndicationContainer) {
mStatusBar = statusBar;
mNotificationIconAreaController = notificationIconAreaController;
- mStatusBarWindow = statusBarWindow;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mNotificationPanel = notificationPanel;
+ mStatusBarWindowViewController = statusBarWindowViewController;
mAmbientIndicationContainer = ambientIndicationContainer;
mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
index 4d6b54c..f3e9b6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -134,6 +134,7 @@
if (fd != null) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inPreferredConfig = Bitmap.Config.HARDWARE;
return LoaderResult.success(BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, options));
} catch (OutOfMemoryError e) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
index f359fe7..b31ce6a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
@@ -77,14 +77,6 @@
void goToKeyguard();
/**
- * When the keyguard is showing and covered by something (bouncer, keyguard activity, etc.) it
- * is occluded. This is controlled by {@link com.android.server.policy.PhoneWindowManager}
- *
- * @return whether the keyguard is currently occluded
- */
- boolean isOccluded();
-
- /**
* Notify the shade controller that the current user changed
*
* @param newUserId userId of the new user
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 170261e..5575d10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -237,9 +237,9 @@
import java.util.Optional;
import javax.inject.Named;
+import javax.inject.Provider;
import dagger.Lazy;
-import dagger.Subcomponent;
public class StatusBar extends SystemUI implements DemoMode,
ActivityStarter, KeyguardStateController.Callback,
@@ -343,6 +343,7 @@
private BiometricUnlockController mBiometricUnlockController;
private final LightBarController mLightBarController;
private final Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
+ @Nullable
protected LockscreenWallpaper mLockscreenWallpaper;
private final AutoHideController mAutoHideController;
@Nullable
@@ -377,9 +378,10 @@
private final FalsingManager mFalsingManager;
private final BroadcastDispatcher mBroadcastDispatcher;
private final ConfigurationController mConfigurationController;
- private final StatusBarWindowViewController mStatusBarWindowViewController;
+ protected StatusBarWindowViewController mStatusBarWindowViewController;
private final DozeParameters mDozeParameters;
private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
+ private final Provider<StatusBarComponent.Builder> mStatusBarComponentBuilder;
private final PluginManager mPluginManager;
private final RemoteInputUriController mRemoteInputUriController;
private final Optional<Divider> mDividerOptional;
@@ -583,6 +585,8 @@
}
}
+ // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
+ // KeyguardCoordinator
@Override
public void onStrongAuthStateChanged(int userId) {
super.onStrongAuthStateChanged(userId);
@@ -659,7 +663,6 @@
NotificationListener notificationListener,
ConfigurationController configurationController,
StatusBarWindowController statusBarWindowController,
- StatusBarWindowViewController statusBarWindowViewController,
LockscreenLockIconController lockscreenLockIconController,
DozeParameters dozeParameters,
ScrimController scrimController,
@@ -673,6 +676,7 @@
VolumeComponent volumeComponent,
CommandQueue commandQueue,
Optional<Recents> recentsOptional,
+ Provider<StatusBarComponent.Builder> statusBarComponentBuilder,
PluginManager pluginManager,
RemoteInputUriController remoteInputUriController,
Optional<Divider> dividerOptional,
@@ -732,7 +736,6 @@
mNotificationListener = notificationListener;
mConfigurationController = configurationController;
mStatusBarWindowController = statusBarWindowController;
- mStatusBarWindowViewController = statusBarWindowViewController;
mLockscreenLockIconController = lockscreenLockIconController;
mDozeServiceHost = dozeServiceHost;
mPowerManager = powerManager;
@@ -746,6 +749,7 @@
mVolumeComponent = volumeComponent;
mCommandQueue = commandQueue;
mRecentsOptional = recentsOptional;
+ mStatusBarComponentBuilder = statusBarComponentBuilder;
mPluginManager = pluginManager;
mRemoteInputUriController = remoteInputUriController;
mDividerOptional = dividerOptional;
@@ -895,7 +899,8 @@
mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
mDozeServiceHost.initialize(this, mNotificationIconAreaController,
- mStatusBarWindow, mStatusBarKeyguardViewManager,
+ mStatusBarKeyguardViewManager,
+ mStatusBarWindowViewController,
mNotificationPanel, mAmbientIndicationContainer);
Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this);
@@ -962,7 +967,7 @@
updateResources();
updateTheme();
- inflateStatusBarWindow(context);
+ inflateStatusBarWindow();
mStatusBarWindowViewController.setService(this);
mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
@@ -1055,7 +1060,7 @@
createNavigationBar(result);
- if (ENABLE_LOCKSCREEN_WALLPAPER) {
+ if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) {
mLockscreenWallpaper = mLockscreenWallpaperLazy.get();
mLockscreenWallpaper.setHandler(mHandler);
}
@@ -1233,7 +1238,8 @@
mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel,
mHeadsUpManager, mStatusBarWindow, mStackScroller, mDozeScrimController,
mScrimController, mActivityLaunchAnimator, mDynamicPrivacyController,
- mNotificationAlertingManager, rowBinder, mKeyguardStateController, mCommandQueue);
+ mNotificationAlertingManager, rowBinder, mKeyguardStateController,
+ this /* statusBar */, mCommandQueue);
mNotificationListController =
new NotificationListController(
@@ -1246,7 +1252,7 @@
mNotificationActivityStarter =
mStatusBarNotificationActivityStarterBuilder
- .setShadeController(this)
+ .setStatusBar(this)
.setActivityLaunchAnimator(mActivityLaunchAnimator)
.setNotificationPresenter(mPresenter)
.build();
@@ -1380,8 +1386,11 @@
mNotificationPanel);
}
- protected void inflateStatusBarWindow(Context context) {
+ private void inflateStatusBarWindow() {
mStatusBarWindow = mSuperStatusBarViewFactory.getStatusBarWindowView();
+ StatusBarComponent statusBarComponent = mStatusBarComponentBuilder.get()
+ .statusBarWindowView(mStatusBarWindow).build();
+ mStatusBarWindowViewController = statusBarComponent.getStatusBarWindowViewController();
mStatusBarWindowViewController.setupExpandedStatusBar();
}
@@ -1751,7 +1760,12 @@
return mAmbientIndicationContainer;
}
- @Override
+ /**
+ * When the keyguard is showing and covered by a "showWhenLocked" activity it
+ * is occluded. This is controlled by {@link com.android.server.policy.PhoneWindowManager}
+ *
+ * @return whether the keyguard is currently occluded
+ */
public boolean isOccluded() {
return mIsOccluded;
}
@@ -2794,7 +2808,9 @@
@Override
public void setLockscreenUser(int newUserId) {
- mLockscreenWallpaper.setCurrentUser(newUserId);
+ if (mLockscreenWallpaper != null) {
+ mLockscreenWallpaper.setCurrentUser(newUserId);
+ }
mScrimController.setCurrentUser(newUserId);
if (mWallpaperSupported) {
mWallpaperChangedReceiver.onReceive(mContext, null);
@@ -4391,11 +4407,6 @@
return mGutsManager;
}
- @Subcomponent
- public interface StatusBarInjector {
- void createStatusBar(StatusBar statusbar);
- }
-
boolean isTransientShown() {
return mTransientShown;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarComponent.java
new file mode 100644
index 0000000..f3c843c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarComponent.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Scope;
+
+import dagger.BindsInstance;
+import dagger.Subcomponent;
+
+/**
+ * Dagger subcomponent tied to the lifecycle of StatusBar views.
+ */
+@Subcomponent
+public interface StatusBarComponent {
+ /**
+ * Builder for {@link StatusBarComponent}.
+ */
+ @Subcomponent.Builder
+ interface Builder {
+ @BindsInstance Builder statusBarWindowView(StatusBarWindowView statusBarWindowView);
+ StatusBarComponent build();
+ }
+
+ /**
+ * Scope annotation for singleton items within the StatusBarComponent.
+ */
+ @Documented
+ @Retention(RUNTIME)
+ @Scope
+ @interface StatusBarScope {}
+
+ /**
+ * Creates a StatusBarWindowViewController.
+ */
+ @StatusBarScope
+ StatusBarWindowViewController getStatusBarWindowViewController();
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
index 5d69409..312c85f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
@@ -77,6 +77,7 @@
import java.util.Optional;
import javax.inject.Named;
+import javax.inject.Provider;
import javax.inject.Singleton;
import dagger.Lazy;
@@ -143,7 +144,6 @@
NotificationListener notificationListener,
ConfigurationController configurationController,
StatusBarWindowController statusBarWindowController,
- StatusBarWindowViewController statusBarWindowViewController,
LockscreenLockIconController lockscreenLockIconController,
DozeParameters dozeParameters,
ScrimController scrimController,
@@ -157,6 +157,7 @@
VolumeComponent volumeComponent,
CommandQueue commandQueue,
Optional<Recents> recentsOptional,
+ Provider<StatusBarComponent.Builder> statusBarComponentBuilder,
PluginManager pluginManager,
RemoteInputUriController remoteInputUriController,
Optional<Divider> dividerOptional,
@@ -217,7 +218,6 @@
notificationListener,
configurationController,
statusBarWindowController,
- statusBarWindowViewController,
lockscreenLockIconController,
dozeParameters,
scrimController,
@@ -231,6 +231,7 @@
volumeComponent,
commandQueue,
recentsOptional,
+ statusBarComponentBuilder,
pluginManager,
remoteInputUriController,
dividerOptional,
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 863874e..e283258 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -93,6 +93,7 @@
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 NotificationEntryManager mEntryManager;
@@ -125,7 +126,8 @@
IDreamManager dreamManager, NotificationRemoteInputManager remoteInputManager,
StatusBarRemoteInputCallback remoteInputCallback, NotificationGroupManager groupManager,
NotificationLockscreenUserManager lockscreenUserManager,
- ShadeController shadeController, KeyguardStateController keyguardStateController,
+ ShadeController shadeController, StatusBar statusBar,
+ KeyguardStateController keyguardStateController,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
MetricsLogger metricsLogger, LockPatternUtils lockPatternUtils,
Handler mainThreadHandler, Handler backgroundHandler,
@@ -142,6 +144,8 @@
mRemoteInputManager = remoteInputManager;
mLockscreenUserManager = lockscreenUserManager;
mShadeController = shadeController;
+ // TODO: use KeyguardStateController#isOccluded to remove this dependency
+ mStatusBar = statusBar;
mKeyguardStateController = keyguardStateController;
mActivityStarter = activityStarter;
mEntryManager = entryManager;
@@ -198,7 +202,7 @@
final boolean afterKeyguardGone = isActivityIntent
&& mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
mLockscreenUserManager.getCurrentUserId());
- final boolean wasOccluded = mShadeController.isOccluded();
+ final boolean wasOccluded = mStatusBar.isOccluded();
boolean showOverLockscreen = mKeyguardStateController.isShowing() && intent != null
&& mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(),
mLockscreenUserManager.getCurrentUserId());
@@ -253,7 +257,7 @@
mShadeController.addPostCollapseAction(runnable);
mShadeController.collapsePanel(true /* animate */);
} else if (mKeyguardStateController.isShowing()
- && mShadeController.isOccluded()) {
+ && mStatusBar.isOccluded()) {
mShadeController.addAfterKeyguardGoneRunnable(runnable);
mShadeController.collapsePanel();
} else {
@@ -384,7 +388,7 @@
.addNextIntentWithParentStack(intent)
.startActivities(getActivityOptions(
mActivityLaunchAnimator.getLaunchAnimation(
- row, mShadeController.isOccluded())),
+ row, mStatusBar.isOccluded())),
new UserHandle(UserHandle.getUserId(appUid)));
mActivityLaunchAnimator.setLaunchResult(launchResult, true /* isActivityIntent */);
if (shouldCollapse()) {
@@ -518,6 +522,7 @@
private ShadeController mShadeController;
private NotificationPresenter mNotificationPresenter;
private ActivityLaunchAnimator mActivityLaunchAnimator;
+ private StatusBar mStatusBar;
@Inject
public Builder(Context context,
@@ -567,8 +572,11 @@
mBubbleController = bubbleController;
mSuperStatusBarViewFactory = superStatusBarViewFactory;
}
- public Builder setShadeController(ShadeController shadeController) {
- mShadeController = shadeController;
+
+ /** Sets the status bar to use as {@link StatusBar} and {@link ShadeController}. */
+ public Builder setStatusBar(StatusBar statusBar) {
+ mStatusBar = statusBar;
+ mShadeController = statusBar;
return this;
}
@@ -600,6 +608,7 @@
mGroupManager,
mLockscreenUserManager,
mShadeController,
+ mStatusBar,
mKeyguardStateController,
mNotificationInterruptionStateProvider,
mMetricsLogger,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 30e26e5..6650cf6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -113,6 +113,7 @@
private final DozeScrimController mDozeScrimController;
private final ScrimController mScrimController;
private final Context mContext;
+ private final StatusBar mStatusBar;
private final CommandQueue mCommandQueue;
private final AccessibilityManager mAccessibilityManager;
@@ -140,12 +141,15 @@
NotificationAlertingManager notificationAlertingManager,
NotificationRowBinderImpl notificationRowBinder,
KeyguardStateController keyguardStateController,
+ StatusBar statusBar,
CommandQueue commandQueue) {
mContext = context;
mKeyguardStateController = keyguardStateController;
mNotificationPanel = panel;
mHeadsUpManager = headsUp;
mDynamicPrivacyController = dynamicPrivacyController;
+ // TODO: use KeyguardStateController#isOccluded to remove this dependency
+ mStatusBar = statusBar;
mCommandQueue = commandQueue;
mAboveShelfObserver = new AboveShelfObserver(stackScroller);
mActivityLaunchAnimator = activityLaunchAnimator;
@@ -330,7 +334,7 @@
}
public boolean canHeadsUp(NotificationEntry entry, StatusBarNotification sbn) {
- if (mShadeController.isOccluded()) {
+ if (mStatusBar.isOccluded()) {
boolean devicePublic = mLockscreenUserManager.
isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
boolean userPublic = devicePublic
@@ -356,7 +360,7 @@
} else {
// we only allow head-up on the lockscreen if it doesn't have a fullscreen intent
return !mKeyguardStateController.isShowing()
- || mShadeController.isOccluded();
+ || mStatusBar.isOccluded();
}
}
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
index feac5da..3935df0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
@@ -43,7 +43,6 @@
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.PulseExpansionHandler;
-import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -57,14 +56,13 @@
import java.io.PrintWriter;
import javax.inject.Inject;
-import javax.inject.Singleton;
import dagger.Lazy;
/**
* Controller for {@link StatusBarWindowView}.
*/
-@Singleton
+//@Singleton
public class StatusBarWindowViewController {
private final InjectionInflationController mInjectionInflationController;
private final NotificationWakeUpCoordinator mCoordinator;
@@ -116,9 +114,9 @@
DozeLog dozeLog,
DozeParameters dozeParameters,
CommandQueue commandQueue,
- SuperStatusBarViewFactory superStatusBarViewFactory,
Lazy<ShadeController> shadeControllerLazy,
- DockManager dockManager) {
+ DockManager dockManager,
+ StatusBarWindowView statusBarWindowView) {
mInjectionInflationController = injectionInflationController;
mCoordinator = coordinator;
mPulseExpansionHandler = pulseExpansionHandler;
@@ -134,7 +132,7 @@
mDozeLog = dozeLog;
mDozeParameters = dozeParameters;
mCommandQueue = commandQueue;
- mView = superStatusBarViewFactory.getStatusBarWindowView();
+ mView = statusBarWindowView;
mShadeControllerLazy = shadeControllerLazy;
mDockManager = dockManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 3f25bb6..b0cd90c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -50,9 +50,9 @@
import java.io.PrintWriter;
import java.util.BitSet;
-import java.util.concurrent.Executor;
-import java.util.Objects;
import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Executor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -552,8 +552,8 @@
// If this is the data subscription, update the currentState data name
if (mCurrentState.networkNameData.equals(mNetworkNameDefault) && mServiceState != null
&& mCurrentState.dataSim
- && !TextUtils.isEmpty(mServiceState.getDataOperatorAlphaShort())) {
- mCurrentState.networkNameData = mServiceState.getDataOperatorAlphaShort();
+ && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) {
+ mCurrentState.networkNameData = mServiceState.getOperatorAlphaShort();
}
notifyListenersIfNecessary();
diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java
new file mode 100644
index 0000000..24f49ff
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java
@@ -0,0 +1,88 @@
+/*
+ * 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 android.content.Context;
+import android.os.Handler;
+
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.BgHandler;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dagger.qualifiers.MainHandler;
+
+import java.util.concurrent.Executor;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Dagger Module for classes found within the concurrent package.
+ */
+@Module
+public abstract class ConcurrencyModule {
+ /**
+ * Provide a Background-Thread Executor by default.
+ */
+ @Provides
+ public static Executor provideExecutor(@BgHandler Handler handler) {
+ return new ExecutorImpl(handler);
+ }
+
+ /**
+ * Provide a Background-Thread Executor.
+ */
+ @Provides
+ @Background
+ public static Executor provideBackgroundExecutor(@BgHandler Handler handler) {
+ return new ExecutorImpl(handler);
+ }
+
+ /**
+ * Provide a Main-Thread Executor.
+ */
+ @Provides
+ @Main
+ public static Executor provideMainExecutor(Context context) {
+ return context.getMainExecutor();
+ }
+
+ /**
+ * Provide a Background-Thread Executor by default.
+ */
+ @Provides
+ public static DelayableExecutor provideDelayableExecutor(@BgHandler Handler handler) {
+ return new ExecutorImpl(handler);
+ }
+
+ /**
+ * Provide a Background-Thread Executor.
+ */
+ @Provides
+ @Background
+ public static DelayableExecutor provideBackgroundDelayableExecutor(@BgHandler Handler handler) {
+ return new ExecutorImpl(handler);
+ }
+
+ /**
+ * Provide a Main-Thread Executor.
+ */
+ @Provides
+ @Main
+ public static DelayableExecutor provideMainDelayableExecutor(@MainHandler Handler handler) {
+ return new ExecutorImpl(handler);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/DelayableExecutor.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/DelayableExecutor.java
new file mode 100644
index 0000000..2d6c4a6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/DelayableExecutor.java
@@ -0,0 +1,72 @@
+/*
+ * 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 Runnables to be delayed and/or cancelled.
+ */
+public interface DelayableExecutor extends Executor {
+ /**
+ * Execute supplied Runnable on the Executors thread after a specified delay.
+ *
+ * See {@link android.os.Handler#postDelayed(Runnable, long)}.
+ *
+ * @return A Runnable that, when run, removes the supplied argument from the Executor queue.
+ */
+ default Runnable executeDelayed(Runnable r, long delayMillis) {
+ return executeDelayed(r, delayMillis, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Execute supplied Runnable on the Executors thread after a specified delay.
+ *
+ * See {@link android.os.Handler#postDelayed(Runnable, long)}.
+ *
+ * @return A Runnable that, when run, removes the supplied argument from the Executor queue..
+ */
+ Runnable executeDelayed(Runnable r, long delay, TimeUnit unit);
+
+ /**
+ * Execute supplied Runnable on the Executors thread at a specified uptime.
+ *
+ * See {@link android.os.Handler#postAtTime(Runnable, long)}.
+ *
+ * @return A Runnable that, when run, removes the supplied argument from the Executor queue.
+ */
+ default Runnable executeAtTime(Runnable r, long uptime) {
+ return executeAtTime(r, uptime, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Execute supplied Runnable on the Executors thread at a specified uptime.
+ *
+ * See {@link android.os.Handler#postAtTime(Runnable, long)}.
+ *
+ * @return A Runnable that, when run, removes the supplied argument from the Executor queue.
+ */
+ Runnable executeAtTime(Runnable r, long uptimeMillis, TimeUnit unit);
+
+ /**
+ * Remove all pending Runnables.
+ *
+ */
+ void removeAll();
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/ExecutorImpl.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/ExecutorImpl.java
new file mode 100644
index 0000000..2a99de3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/ExecutorImpl.java
@@ -0,0 +1,58 @@
+/*
+ * 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 android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.Message;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implementations of {@link DelayableExecutor} for SystemUI.
+ */
+public class ExecutorImpl extends HandlerExecutor implements DelayableExecutor {
+ private final Handler mHandler;
+
+ public ExecutorImpl(Handler handler) {
+ super(handler);
+ mHandler = handler;
+ }
+
+ @Override
+ public Runnable executeDelayed(Runnable r, long delay, TimeUnit unit) {
+ Object token = new Object();
+ Message m = mHandler.obtainMessage(0, token);
+ mHandler.sendMessageDelayed(m, unit.toMillis(delay));
+
+ return () -> mHandler.removeCallbacksAndMessages(token);
+ }
+
+ @Override
+ public Runnable executeAtTime(Runnable r, long uptimeMillis, TimeUnit unit) {
+ Object token = new Object();
+ Message m = mHandler.obtainMessage(0, token);
+ mHandler.sendMessageAtTime(m, unit.toMillis(uptimeMillis));
+
+ return () -> mHandler.removeCallbacksAndMessages(token);
+ }
+
+ @Override
+ public void removeAll() {
+ mHandler.removeCallbacksAndMessages(null);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 8c9f759..4c707f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -157,9 +157,14 @@
private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
private BubbleData mBubbleData;
+ private TestableLooper mTestableLooper;
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+
+ mTestableLooper = TestableLooper.get(this);
+
mContext.addMockSystemService(FaceManager.class, mFaceManager);
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
@@ -262,7 +267,7 @@
mRow.getEntry().getKey()));
// Make it look like dismissed notif
- mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).setShowInShadeWhenBubble(false);
+ mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).setShowInShade(false);
// Now remove the bubble
mBubbleController.removeBubble(
@@ -346,14 +351,14 @@
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().getKey());
// Last added is the one that is expanded
- assertEquals(mRow2.getEntry(), stackView.getExpandedBubbleView().getEntry());
+ assertEquals(mRow2.getEntry(), mBubbleData.getSelectedBubble().getEntry());
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
mRow2.getEntry().getKey()));
// Switch which bubble is expanded
mBubbleController.selectBubble(mRow.getEntry().getKey());
stackView.setExpandedBubble(mRow.getEntry().getKey());
- assertEquals(mRow.getEntry(), stackView.getExpandedBubbleView().getEntry());
+ assertEquals(mRow.getEntry(), stackView.getExpandedBubble().getEntry());
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
mRow.getEntry().getKey()));
@@ -377,7 +382,9 @@
assertTrue(mBubbleController.hasBubbles());
assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
mRow.getEntry().getKey()));
- assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showBubbleDot());
+
+ mTestableLooper.processAllMessages();
+ assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot());
// Expand
mBubbleController.expandStack();
@@ -388,7 +395,7 @@
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
mRow.getEntry().getKey()));
// Notif shouldn't show dot after expansion
- assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showBubbleDot());
+ assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot());
}
@Test
@@ -401,10 +408,11 @@
assertTrue(mBubbleController.hasBubbles());
assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
mRow.getEntry().getKey()));
- assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showBubbleDot());
+
+ mTestableLooper.processAllMessages();
+ assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot());
// Expand
- BubbleStackView stackView = mBubbleController.getStackView();
mBubbleController.expandStack();
assertTrue(mBubbleController.isStackExpanded());
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
@@ -413,7 +421,7 @@
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
mRow.getEntry().getKey()));
// Notif shouldn't show dot after expansion
- assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showBubbleDot());
+ assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot());
// Send update
mEntryListener.onPreEntryUpdated(mRow.getEntry());
@@ -423,7 +431,7 @@
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
mRow.getEntry().getKey()));
// Notif shouldn't show dot after expansion
- assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showBubbleDot());
+ assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot());
}
@Test
@@ -443,7 +451,7 @@
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().getKey());
// Last added is the one that is expanded
- assertEquals(mRow2.getEntry(), stackView.getExpandedBubbleView().getEntry());
+ assertEquals(mRow2.getEntry(), stackView.getExpandedBubble().getEntry());
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
mRow2.getEntry().getKey()));
@@ -453,7 +461,7 @@
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().getKey());
// Make sure first bubble is selected
- assertEquals(mRow.getEntry(), stackView.getExpandedBubbleView().getEntry());
+ assertEquals(mRow.getEntry(), stackView.getExpandedBubble().getEntry());
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
// Dismiss that one
@@ -555,7 +563,9 @@
mEntryListener.onPendingEntryAdded(mRow.getEntry());
assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
mRow.getEntry().getKey()));
- assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showBubbleDot());
+
+ mTestableLooper.processAllMessages();
+ assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
index a9be30b..95c7af3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
@@ -183,7 +183,7 @@
// Verify
verifyUpdateReceived();
BubbleData.Update update = mUpdateCaptor.getValue();
- assertThat(update.addedBubble.showFlyoutForBubble()).isFalse();
+ assertThat(update.addedBubble.showFlyout()).isFalse();
}
@Test
@@ -199,7 +199,7 @@
// Verify
verifyUpdateReceived();
BubbleData.Update update = mUpdateCaptor.getValue();
- assertThat(update.addedBubble.showFlyoutForBubble()).isTrue();
+ assertThat(update.addedBubble.showFlyout()).isTrue();
}
@Test
@@ -218,7 +218,7 @@
// Verify
BubbleData.Update update = mUpdateCaptor.getValue();
- assertThat(update.updatedBubble.showFlyoutForBubble()).isFalse();
+ assertThat(update.updatedBubble.showFlyout()).isFalse();
}
@Test
@@ -239,7 +239,7 @@
// Verify
BubbleData.Update update = mUpdateCaptor.getValue();
- assertThat(update.updatedBubble.showFlyoutForBubble()).isTrue();
+ assertThat(update.updatedBubble.showFlyout()).isTrue();
}
// COLLAPSED / ADD
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleFlyoutViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleFlyoutViewTest.java
index a8961a8..376ecf7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleFlyoutViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleFlyoutViewTest.java
@@ -60,7 +60,8 @@
@Test
public void testShowFlyout_isVisible() {
mFlyout.setupFlyoutStartingAsDot(
- "Hello", new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter);
+ "Hello", new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter,
+ false);
mFlyout.setVisibility(View.VISIBLE);
assertEquals("Hello", mFlyoutText.getText());
@@ -71,7 +72,8 @@
public void testFlyoutHide_runsCallback() {
Runnable after = Mockito.mock(Runnable.class);
mFlyout.setupFlyoutStartingAsDot(
- "Hello", new PointF(100, 100), 500, true, Color.WHITE, null, after, mDotCenter);
+ "Hello", new PointF(100, 100), 500, true, Color.WHITE, null, after, mDotCenter,
+ false);
mFlyout.hideFlyout();
verify(after).run();
@@ -80,7 +82,8 @@
@Test
public void testSetCollapsePercent() {
mFlyout.setupFlyoutStartingAsDot(
- "Hello", new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter);
+ "Hello", new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter,
+ false);
mFlyout.setVisibility(View.VISIBLE);
mFlyout.setCollapsePercent(1f);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/RichEventTest.java b/packages/SystemUI/tests/src/com/android/systemui/log/RichEventTest.java
index 4a90bb9..2f90641 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/RichEventTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/RichEventTest.java
@@ -57,7 +57,7 @@
class TestableRichEvent extends RichEvent {
TestableRichEvent(int logLevel, int type, String reason) {
- init(logLevel, type, reason);
+ super(logLevel, type, reason);
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/SysuiLogTest.java b/packages/SystemUI/tests/src/com/android/systemui/log/SysuiLogTest.java
index 0dfb7ba8..378bba1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/SysuiLogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/SysuiLogTest.java
@@ -35,12 +35,11 @@
@RunWith(AndroidTestingRunner.class)
public class SysuiLogTest extends SysuiTestCase {
private static final String TEST_ID = "TestLogger";
- private static final String TEST_MSG = "msg";
private static final int MAX_LOGS = 5;
@Mock
private DumpController mDumpController;
- private SysuiLog<Event> mSysuiLog;
+ private SysuiLog mSysuiLog;
@Before
public void setup() {
@@ -49,63 +48,35 @@
@Test
public void testLogDisabled_noLogsWritten() {
- mSysuiLog = new TestSysuiLog(mDumpController, TEST_ID, MAX_LOGS, false);
- assertEquals(null, mSysuiLog.mTimeline);
+ mSysuiLog = new SysuiLog(mDumpController, TEST_ID, MAX_LOGS, false);
+ assertEquals(mSysuiLog.mTimeline, null);
- mSysuiLog.log(createEvent(TEST_MSG));
- assertEquals(null, mSysuiLog.mTimeline);
+ mSysuiLog.log(new Event("msg"));
+ assertEquals(mSysuiLog.mTimeline, null);
}
@Test
public void testLogEnabled_logWritten() {
- mSysuiLog = new TestSysuiLog(mDumpController, TEST_ID, MAX_LOGS, true);
- assertEquals(0, mSysuiLog.mTimeline.size());
+ mSysuiLog = new SysuiLog(mDumpController, TEST_ID, MAX_LOGS, true);
+ assertEquals(mSysuiLog.mTimeline.size(), 0);
- mSysuiLog.log(createEvent(TEST_MSG));
- assertEquals(1, mSysuiLog.mTimeline.size());
+ mSysuiLog.log(new Event("msg"));
+ assertEquals(mSysuiLog.mTimeline.size(), 1);
}
@Test
public void testMaxLogs() {
- mSysuiLog = new TestSysuiLog(mDumpController, TEST_ID, MAX_LOGS, true);
+ mSysuiLog = new SysuiLog(mDumpController, TEST_ID, MAX_LOGS, true);
assertEquals(mSysuiLog.mTimeline.size(), 0);
+ final String msg = "msg";
for (int i = 0; i < MAX_LOGS + 1; i++) {
- mSysuiLog.log(createEvent(TEST_MSG + i));
+ mSysuiLog.log(new Event(msg + i));
}
- assertEquals(MAX_LOGS, mSysuiLog.mTimeline.size());
+ assertEquals(mSysuiLog.mTimeline.size(), MAX_LOGS);
- // check the first message (msg0) was replaced with msg1:
- assertEquals(TEST_MSG + "1", mSysuiLog.mTimeline.getFirst().getMessage());
- }
-
- @Test
- public void testRecycleLogs() {
- // GIVEN a SysuiLog with one log
- mSysuiLog = new TestSysuiLog(mDumpController, TEST_ID, MAX_LOGS, true);
- Event e = createEvent(TEST_MSG); // msg
- mSysuiLog.log(e); // Logs: [msg]
-
- Event recycledEvent = null;
- // WHEN we add MAX_LOGS after the first log
- for (int i = 0; i < MAX_LOGS; i++) {
- recycledEvent = mSysuiLog.log(createEvent(TEST_MSG + i));
- }
- // Logs: [msg1, msg2, msg3, msg4]
-
- // THEN we see the recycledEvent is e
- assertEquals(e, recycledEvent);
- }
-
- private Event createEvent(String msg) {
- return new Event().init(msg);
- }
-
- public class TestSysuiLog extends SysuiLog<Event> {
- protected TestSysuiLog(DumpController dumpController, String id, int maxLogs,
- boolean enabled) {
- super(dumpController, id, maxLogs, enabled);
- }
+ // check the first message (msg0) is deleted:
+ assertEquals(mSysuiLog.mTimeline.getFirst().getMessage(), msg + "1");
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
index b41512c..39ce8c1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
@@ -36,13 +36,9 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.os.Handler;
-import android.os.Looper;
import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -52,6 +48,8 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
@@ -69,7 +67,6 @@
@SmallTest
@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
public class TileQueryHelperTest extends SysuiTestCase {
private static final String CURRENT_TILES = "wifi,dnd,nfc";
private static final String ONLY_STOCK_TILES = "wifi,dnd";
@@ -98,14 +95,13 @@
private ArgumentCaptor<List<TileQueryHelper.TileInfo>> mCaptor;
private QSTile.State mState;
- private TestableLooper mBGLooper;
private TileQueryHelper mTileQueryHelper;
- private Handler mMainHandler;
+ private FakeExecutor mMainExecutor;
+ private FakeExecutor mBgExecutor;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mBGLooper = TestableLooper.get(this);
mContext.setMockPackageManager(mPackageManager);
mState = new QSTile.State();
@@ -123,9 +119,11 @@
}
).when(mQSTileHost).createTile(anyString());
- mMainHandler = new Handler(Looper.getMainLooper());
- mTileQueryHelper = new TileQueryHelper(mContext, mMainHandler,
- new Handler(mBGLooper.getLooper()));
+ FakeSystemClock clock = new FakeSystemClock();
+ clock.setAutoIncrement(false);
+ mMainExecutor = new FakeExecutor(clock);
+ mBgExecutor = new FakeExecutor(clock);
+ mTileQueryHelper = new TileQueryHelper(mContext, mMainExecutor, mBgExecutor);
mTileQueryHelper.setListener(mListener);
}
@@ -138,8 +136,7 @@
public void testIsFinished_trueAfterQuerying() {
mTileQueryHelper.queryTiles(mQSTileHost);
- mBGLooper.processAllMessages();
- waitForIdleSync(mMainHandler);
+ FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
assertTrue(mTileQueryHelper.isFinished());
}
@@ -148,8 +145,7 @@
public void testQueryTiles_callsListenerTwice() {
mTileQueryHelper.queryTiles(mQSTileHost);
- mBGLooper.processAllMessages();
- waitForIdleSync(mMainHandler);
+ FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
verify(mListener, times(2)).onTilesChanged(any());
}
@@ -163,8 +159,7 @@
mTileQueryHelper.queryTiles(mQSTileHost);
- mBGLooper.processAllMessages();
- waitForIdleSync(mMainHandler);
+ FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
assertTrue(mTileQueryHelper.isFinished());
}
@@ -178,8 +173,7 @@
mTileQueryHelper.queryTiles(mQSTileHost);
- mBGLooper.processAllMessages();
- waitForIdleSync(mMainHandler);
+ FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
verify(mListener, atLeastOnce()).onTilesChanged(mCaptor.capture());
List<String> specs = new ArrayList<>();
@@ -199,8 +193,7 @@
mTileQueryHelper.queryTiles(mQSTileHost);
- mBGLooper.processAllMessages();
- waitForIdleSync(mMainHandler);
+ FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
verify(mListener, atLeastOnce()).onTilesChanged(mCaptor.capture());
List<String> specs = new ArrayList<>();
@@ -220,8 +213,7 @@
mTileQueryHelper.queryTiles(mQSTileHost);
- mBGLooper.processAllMessages();
- waitForIdleSync(mMainHandler);
+ FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
verify(mListener, atLeastOnce()).onTilesChanged(mCaptor.capture());
List<String> specs = new ArrayList<>();
@@ -251,8 +243,7 @@
"");
mTileQueryHelper.queryTiles(mQSTileHost);
- mBGLooper.processAllMessages();
- waitForIdleSync(mMainHandler);
+ FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
verify(mListener, atLeastOnce()).onTilesChanged(mCaptor.capture());
List<TileQueryHelper.TileInfo> tileInfos = mCaptor.getValue();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index a98945f..e0dfe7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -85,6 +85,7 @@
import com.android.systemui.statusbar.notification.collection.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.RowInflaterTask;
@@ -228,7 +229,8 @@
mHeadsUpManager,
mock(NotificationFilter.class),
mNotifLog,
- mock(NotificationSectionsFeatureManager.class)),
+ mock(NotificationSectionsFeatureManager.class),
+ mock(PeopleNotificationIdentifier.class)),
mEnvironment
);
Dependency.get(InitController.class).executePostInitTasks();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java
index 6d56b06..a25af84 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java
@@ -47,7 +47,6 @@
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.SectionsProvider;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.util.Assert;
import com.android.systemui.util.time.FakeSystemClock;
@@ -77,7 +76,6 @@
private NotifListBuilderImpl mListBuilder;
private FakeSystemClock mSystemClock = new FakeSystemClock();
- @Mock private NotifLog mNotifLog;
@Mock private NotifCollection mNotifCollection;
@Spy private OnBeforeTransformGroupsListener mOnBeforeTransformGroupsListener;
@Spy private OnBeforeSortListener mOnBeforeSortListener;
@@ -99,7 +97,7 @@
MockitoAnnotations.initMocks(this);
Assert.sMainLooper = TestableLooper.get(this).getLooper();
- mListBuilder = new NotifListBuilderImpl(mSystemClock, mNotifLog);
+ mListBuilder = new NotifListBuilderImpl(mSystemClock);
mListBuilder.setOnRenderListListener(mOnRenderListListener);
mListBuilder.attach(mNotifCollection);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
index 01b2f89..cda1538e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
@@ -20,7 +20,6 @@
import android.app.NotificationChannel
import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_LOW
-import android.app.Person
import android.service.notification.NotificationListenerService.RankingMap
import android.service.notification.StatusBarNotification
import android.testing.AndroidTestingRunner
@@ -36,6 +35,7 @@
import com.android.systemui.statusbar.notification.NotificationFilter
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.logging.NotifLog
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT
import com.android.systemui.statusbar.phone.NotificationGroupManager
@@ -52,42 +52,39 @@
@SmallTest
@RunWith(AndroidTestingRunner::class)
-class NotificationRankingManagerTest
- : SysuiTestCase() {
+class NotificationRankingManagerTest : SysuiTestCase() {
- private var lazyMedia: Lazy<NotificationMediaManager> = Lazy {
- mock<NotificationMediaManager>(NotificationMediaManager::class.java)
+ private val lazyMedia: Lazy<NotificationMediaManager> = Lazy {
+ mock(NotificationMediaManager::class.java)
}
-
- private val rankingManager = TestableNotificationRankingManager(
- lazyMedia,
- mock<NotificationGroupManager>(NotificationGroupManager::class.java),
- mock<HeadsUpManager>(HeadsUpManager::class.java),
- mock<NotificationFilter>(NotificationFilter::class.java),
- mock<NotifLog>(NotifLog::class.java),
- mock<NotificationSectionsFeatureManager>(NotificationSectionsFeatureManager::class.java)
- )
+ private lateinit var personNotificationIdentifier: PeopleNotificationIdentifier
+ private lateinit var rankingManager: TestableNotificationRankingManager
@Before
fun setup() {
+ personNotificationIdentifier =
+ mock(PeopleNotificationIdentifier::class.java)
+ rankingManager = TestableNotificationRankingManager(
+ lazyMedia,
+ mock(NotificationGroupManager::class.java),
+ mock(HeadsUpManager::class.java),
+ mock(NotificationFilter::class.java),
+ mock(NotifLog::class.java),
+ mock(NotificationSectionsFeatureManager::class.java),
+ personNotificationIdentifier
+ )
}
@Test
fun testPeopleNotification_isHighPriority() {
- val person = Person.Builder()
- .setName("name")
- .setKey("abc")
- .setUri("uri")
- .setBot(true)
- .build()
-
val notification = Notification.Builder(mContext, "test")
- .addPerson(person)
.build()
val sbn = StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
notification, mContext.user, "", 0)
+ `when`(personNotificationIdentifier.isPeopleNotification(sbn)).thenReturn(true)
+
val e = NotificationEntryBuilder()
.setNotification(notification)
.setSbn(sbn)
@@ -97,27 +94,9 @@
}
@Test
- fun messagingStyleHighPriority() {
-
- val notif = Notification.Builder(mContext, "test")
- .setStyle(Notification.MessagingStyle(""))
- .build()
-
- val sbn = StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
- notif, mContext.getUser(), "", 0)
-
- val e = NotificationEntryBuilder()
- .setNotification(notif)
- .setSbn(sbn)
- .build()
-
- assertTrue(rankingManager.isHighPriority2(e))
- }
-
- @Test
fun lowForegroundHighPriority() {
val notification = mock(Notification::class.java)
- `when`<Boolean>(notification.isForegroundService).thenReturn(true)
+ `when`(notification.isForegroundService).thenReturn(true)
val sbn = StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
notification, mContext.user, "", 0)
@@ -136,15 +115,7 @@
@Test
fun userChangeTrumpsHighPriorityCharacteristics() {
- val person = Person.Builder()
- .setName("name")
- .setKey("abc")
- .setUri("uri")
- .setBot(true)
- .build()
-
val notification = Notification.Builder(mContext, "test")
- .addPerson(person)
.setStyle(Notification.MessagingStyle(""))
.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
.build()
@@ -152,6 +123,8 @@
val sbn = StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
notification, mContext.user, "", 0)
+ `when`(personNotificationIdentifier.isPeopleNotification(sbn)).thenReturn(true)
+
val channel = NotificationChannel("a", "a", IMPORTANCE_LOW)
channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE)
@@ -297,14 +270,16 @@
headsUpManager: HeadsUpManager,
filter: NotificationFilter,
notifLog: NotifLog,
- sectionsFeatureManager: NotificationSectionsFeatureManager
+ sectionsFeatureManager: NotificationSectionsFeatureManager,
+ peopleNotificationIdentifier: PeopleNotificationIdentifier
) : NotificationRankingManager(
mediaManager,
groupManager,
headsUpManager,
filter,
notifLog,
- sectionsFeatureManager
+ sectionsFeatureManager,
+ peopleNotificationIdentifier
) {
fun isHighPriority2(e: NotificationEntry): Boolean {
@@ -315,4 +290,4 @@
rankingMap = r
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index d20a37a..d2b4a20 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -74,6 +74,7 @@
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.statusbar.notification.people.PeopleHubSectionFooterViewAdapter;
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.FooterView;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
@@ -164,7 +165,8 @@
mHeadsUpManager,
mock(NotificationFilter.class),
mock(NotifLog.class),
- mock(NotificationSectionsFeatureManager.class)
+ mock(NotificationSectionsFeatureManager.class),
+ mock(PeopleNotificationIdentifier.class)
),
mock(NotificationEntryManager.KeyguardEnvironment.class));
mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 222fcb6..46f6cfe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -85,7 +85,6 @@
@Mock private StatusBar mStatusBar;
@Mock private NotificationIconAreaController mNotificationIconAreaController;
@Mock private StatusBarWindowViewController mStatusBarWindowViewController;
- @Mock private StatusBarWindowView mStatusBarWindow;
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock private NotificationPanelView mNotificationPanel;
@Mock private View mAmbientIndicationContainer;
@@ -101,10 +100,11 @@
mKeyguardViewMediator, () -> mAssistManager, mDozeScrimController,
mKeyguardUpdateMonitor, mVisualStabilityManager, mPulseExpansionHandler,
mStatusBarWindowController, mNotificationWakeUpCoordinator,
- mStatusBarWindowViewController, mLockscreenLockIconController);
+ mLockscreenLockIconController);
- mDozeServiceHost.initialize(mStatusBar, mNotificationIconAreaController, mStatusBarWindow,
- mStatusBarKeyguardViewManager, mNotificationPanel, mAmbientIndicationContainer);
+ mDozeServiceHost.initialize(mStatusBar, mNotificationIconAreaController,
+ mStatusBarKeyguardViewManager, mStatusBarWindowViewController, mNotificationPanel,
+ mAmbientIndicationContainer);
}
@Test
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 6f5cfbe..77cdc02 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
@@ -102,7 +102,7 @@
@Mock
private RemoteInputController mRemoteInputController;
@Mock
- private ShadeController mShadeController;
+ private StatusBar mStatusBar;
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
@@ -175,7 +175,7 @@
mock(NotificationInterruptionStateProvider.class), mock(MetricsLogger.class),
mock(LockPatternUtils.class), mHandler, mHandler, mActivityIntentHelper,
mBubbleController, mSuperStatusBarViewFactory))
- .setShadeController(mShadeController)
+ .setStatusBar(mStatusBar)
.setNotificationPresenter(mock(NotificationPresenter.class))
.setActivityLaunchAnimator(mock(ActivityLaunchAnimator.class))
.build();
@@ -186,11 +186,11 @@
// set up addAfterKeyguardGoneRunnable to synchronously invoke the Runnable arg
doAnswer(answerVoid(Runnable::run))
- .when(mShadeController).addAfterKeyguardGoneRunnable(any(Runnable.class));
+ .when(mStatusBar).addAfterKeyguardGoneRunnable(any(Runnable.class));
// set up addPostCollapseAction to synchronously invoke the Runnable arg
doAnswer(answerVoid(Runnable::run))
- .when(mShadeController).addPostCollapseAction(any(Runnable.class));
+ .when(mStatusBar).addPostCollapseAction(any(Runnable.class));
// set up Handler to synchronously invoke the Runnable arg
doAnswer(answerVoid(Runnable::run))
@@ -209,13 +209,13 @@
sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
when(mKeyguardStateController.isShowing()).thenReturn(true);
- when(mShadeController.isOccluded()).thenReturn(true);
+ when(mStatusBar.isOccluded()).thenReturn(true);
// When
mNotificationActivityStarter.onNotificationClicked(sbn, mNotificationRow);
// Then
- verify(mShadeController, atLeastOnce()).collapsePanel();
+ verify(mStatusBar, atLeastOnce()).collapsePanel();
verify(mContentIntent).sendAndReturnResult(
any(Context.class),
@@ -250,7 +250,7 @@
verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey()));
// This is called regardless, and simply short circuits when there is nothing to do.
- verify(mShadeController, atLeastOnce()).collapsePanel();
+ verify(mStatusBar, atLeastOnce()).collapsePanel();
verify(mAssistManager).hideAssist();
@@ -272,7 +272,7 @@
// Given
sbn.getNotification().contentIntent = null;
when(mKeyguardStateController.isShowing()).thenReturn(true);
- when(mShadeController.isOccluded()).thenReturn(true);
+ when(mStatusBar.isOccluded()).thenReturn(true);
// When
mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow);
@@ -280,7 +280,7 @@
// Then
verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey()));
- verify(mShadeController, atLeastOnce()).collapsePanel();
+ verify(mStatusBar, atLeastOnce()).collapsePanel();
verify(mAssistManager).hideAssist();
@@ -302,7 +302,7 @@
// Given
sbn.getNotification().contentIntent = mContentIntent;
when(mKeyguardStateController.isShowing()).thenReturn(true);
- when(mShadeController.isOccluded()).thenReturn(true);
+ when(mStatusBar.isOccluded()).thenReturn(true);
// When
mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow);
@@ -310,7 +310,7 @@
// Then
verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey()));
- verify(mShadeController, atLeastOnce()).collapsePanel();
+ verify(mStatusBar, atLeastOnce()).collapsePanel();
verify(mAssistManager).hideAssist();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 1c02b60..14f5795 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -71,10 +71,11 @@
public class StatusBarNotificationPresenterTest extends SysuiTestCase {
- private StatusBarNotificationPresenter mStatusBar;
+ private StatusBarNotificationPresenter mStatusBarNotificationPresenter;
private CommandQueue mCommandQueue;
private FakeMetricsLogger mMetricsLogger;
private ShadeController mShadeController = mock(ShadeController.class);
+ private StatusBar mStatusBar = mock(StatusBar.class);
@Before
public void setup() {
@@ -105,14 +106,14 @@
StatusBarWindowView statusBarWindowView = mock(StatusBarWindowView.class);
when(statusBarWindowView.getResources()).thenReturn(mContext.getResources());
- mStatusBar = new StatusBarNotificationPresenter(mContext,
+ mStatusBarNotificationPresenter = new StatusBarNotificationPresenter(mContext,
mock(NotificationPanelView.class), mock(HeadsUpManagerPhone.class),
statusBarWindowView, mock(NotificationListContainerViewGroup.class),
mock(DozeScrimController.class), mock(ScrimController.class),
mock(ActivityLaunchAnimator.class), mock(DynamicPrivacyController.class),
mock(NotificationAlertingManager.class),
mock(NotificationRowBinderImpl.class), mock(KeyguardStateController.class),
- mCommandQueue);
+ mStatusBar, mCommandQueue);
}
@Test
@@ -129,7 +130,7 @@
TestableLooper.get(this).processAllMessages();
assertFalse("The panel shouldn't allow heads up while disabled",
- mStatusBar.canHeadsUp(entry, entry.getSbn()));
+ mStatusBarNotificationPresenter.canHeadsUp(entry, entry.getSbn()));
}
@Test
@@ -146,13 +147,13 @@
TestableLooper.get(this).processAllMessages();
assertFalse("The panel shouldn't allow heads up while notitifcation shade disabled",
- mStatusBar.canHeadsUp(entry, entry.getSbn()));
+ mStatusBarNotificationPresenter.canHeadsUp(entry, entry.getSbn()));
}
@Test
public void onActivatedMetrics() {
ActivatableNotificationView view = mock(ActivatableNotificationView.class);
- mStatusBar.onActivated(view);
+ mStatusBarNotificationPresenter.onActivated(view);
MetricsAsserts.assertHasLog("missing lockscreen note tap log",
mMetricsLogger.getLogs(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index e78fb9e..be68097 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -145,6 +145,8 @@
import java.util.ArrayList;
import java.util.Optional;
+import javax.inject.Provider;
+
import dagger.Lazy;
@SmallTest
@@ -227,6 +229,9 @@
@Mock private VolumeComponent mVolumeComponent;
@Mock private CommandQueue mCommandQueue;
@Mock private Recents mRecents;
+ @Mock private Provider<StatusBarComponent.Builder> mStatusBarComponentBuilderProvider;
+ @Mock private StatusBarComponent.Builder mStatusBarComponentBuilder;
+ @Mock private StatusBarComponent mStatusBarComponent;
@Mock private PluginManager mPluginManager;
@Mock private Divider mDivider;
@Mock private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
@@ -300,6 +305,11 @@
when(mLockscreenWallpaperLazy.get()).thenReturn(mLockscreenWallpaper);
when(mBiometricUnlockControllerLazy.get()).thenReturn(mBiometricUnlockController);
+ when(mStatusBarComponentBuilderProvider.get()).thenReturn(mStatusBarComponentBuilder);
+ when(mStatusBarComponentBuilder.build()).thenReturn(mStatusBarComponent);
+ when(mStatusBarComponent.getStatusBarWindowViewController()).thenReturn(
+ mStatusBarWindowViewController);
+
mStatusBar = new StatusBar(
mContext,
mFeatureFlags,
@@ -354,7 +364,6 @@
mNotificationListener,
configurationController,
mStatusBarWindowController,
- mStatusBarWindowViewController,
mLockscreenLockIconController,
mDozeParameters,
mScrimController,
@@ -367,6 +376,7 @@
mVolumeComponent,
mCommandQueue,
Optional.of(mRecents),
+ mStatusBarComponentBuilderProvider,
mPluginManager,
mRemoteInputUriController,
Optional.of(mDivider),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
index ee9ea9f..529333e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
@@ -36,7 +36,6 @@
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.PulseExpansionHandler;
-import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -74,7 +73,6 @@
@Mock private StatusBar mStatusBar;
@Mock private DozeLog mDozeLog;
@Mock private DozeParameters mDozeParameters;
- @Mock private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
@Mock private DockManager mDockManager;
@Before
@@ -85,7 +83,6 @@
when(mStatusBar.isDozing()).thenReturn(false);
mDependency.injectTestDependency(ShadeController.class, mShadeController);
- when(mSuperStatusBarViewFactory.getStatusBarWindowView()).thenReturn(mView);
when(mDockManager.isDocked()).thenReturn(false);
mController = new StatusBarWindowViewController(
@@ -105,9 +102,9 @@
mDozeLog,
mDozeParameters,
new CommandQueue(mContext),
- mSuperStatusBarViewFactory,
() -> mShadeController,
- mDockManager);
+ mDockManager,
+ mView);
mController.setupExpandedStatusBar();
mController.setService(mStatusBar);
mController.setDragDownHelper(mDragDownHelper);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index ab74caa..95b055c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -500,7 +500,7 @@
public void testUpdateDataNetworkName() {
setupDefaultSignal();
String newDataName = "TestDataName";
- when(mServiceState.getDataOperatorAlphaShort()).thenReturn(newDataName);
+ when(mServiceState.getOperatorAlphaShort()).thenReturn(newDataName);
updateServiceState();
assertDataNetworkNameEquals(newDataName);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutor.java b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutor.java
new file mode 100644
index 0000000..3ed6c5b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutor.java
@@ -0,0 +1,227 @@
+/*
+ * 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 com.android.systemui.util.time.FakeSystemClock;
+import com.android.systemui.util.time.FakeSystemClock.ClockTickListener;
+
+import java.util.Collections;
+import java.util.PriorityQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class FakeExecutor implements DelayableExecutor {
+ private final FakeSystemClock mClock;
+ private PriorityQueue<QueuedRunnable> mQueuedRunnables = new PriorityQueue<>();
+ private boolean mIgnoreClockUpdates;
+
+ private ClockTickListener mClockTickListener = new ClockTickListener() {
+ @Override
+ public void onUptimeMillis(long uptimeMillis) {
+ if (!mIgnoreClockUpdates) {
+ runAllReady();
+ }
+ }
+ };
+
+ /**
+ * Initializes a fake executor.
+ *
+ * @param clock FakeSystemClock allowing control over delayed runnables. It is strongly
+ * recommended that this clock have its auto-increment setting set to false to
+ * prevent unexpected advancement of the time.
+ */
+ public FakeExecutor(FakeSystemClock clock) {
+ mClock = clock;
+ mClock.addListener(mClockTickListener);
+ }
+
+ /**
+ * Runs a single runnable if it's scheduled to run according to the internal clock.
+ *
+ * If constructed to advance the clock automatically, this will advance the clock enough to
+ * run the next pending item.
+ *
+ * This method does not advance the clock past the item that was run.
+ *
+ * @return Returns true if an item was run.
+ */
+ public boolean runNextReady() {
+ if (!mQueuedRunnables.isEmpty() && mQueuedRunnables.peek().mWhen <= mClock.uptimeMillis()) {
+ mQueuedRunnables.poll().mRunnable.run();
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Runs all Runnables that are scheduled to run according to the internal clock.
+ *
+ * If constructed to advance the clock automatically, this will advance the clock enough to
+ * run all the pending items. This method does not advance the clock past items that were
+ * run. It is equivalent to calling {@link #runNextReady()} in a loop.
+ *
+ * @return Returns the number of items that ran.
+ */
+ public int runAllReady() {
+ int num = 0;
+ while (runNextReady()) {
+ num++;
+ }
+
+ return num;
+ }
+
+ /**
+ * Advances the internal clock to the next item to run.
+ *
+ * The clock will only move forward. If the next item is set to run in the past or there is no
+ * next item, the clock does not change.
+ *
+ * Note that this will cause one or more items to actually run.
+ *
+ * @return The delta in uptimeMillis that the clock advanced, or 0 if the clock did not advance.
+ */
+ public long advanceClockToNext() {
+ if (mQueuedRunnables.isEmpty()) {
+ return 0;
+ }
+
+ long startTime = mClock.uptimeMillis();
+ long nextTime = mQueuedRunnables.peek().mWhen;
+ if (nextTime <= startTime) {
+ return 0;
+ }
+ updateClock(nextTime);
+
+ return nextTime - startTime;
+ }
+
+
+ /**
+ * Advances the internal clock to the last item to run.
+ *
+ * The clock will only move forward. If the last item is set to run in the past or there is no
+ * next item, the clock does not change.
+ *
+ * @return The delta in uptimeMillis that the clock advanced, or 0 if the clock did not advance.
+ */
+ public long advanceClockToLast() {
+ if (mQueuedRunnables.isEmpty()) {
+ return 0;
+ }
+
+ long startTime = mClock.uptimeMillis();
+ long nextTime = Collections.max(mQueuedRunnables).mWhen;
+ if (nextTime <= startTime) {
+ return 0;
+ }
+
+ updateClock(nextTime);
+
+ return nextTime - startTime;
+ }
+
+ /**
+ * Returns the number of un-executed runnables waiting to run.
+ */
+ public int numPending() {
+ return mQueuedRunnables.size();
+ }
+
+ @Override
+ public Runnable executeDelayed(Runnable r, long delay, TimeUnit unit) {
+ if (delay < 0) {
+ delay = 0;
+ }
+ return executeAtTime(r, mClock.uptimeMillis() + unit.toMillis(delay));
+ }
+
+ @Override
+ public Runnable executeAtTime(Runnable r, long uptime, TimeUnit unit) {
+ long uptimeMillis = unit.toMillis(uptime);
+
+ QueuedRunnable container = new QueuedRunnable(r, uptimeMillis);
+
+ mQueuedRunnables.offer(container);
+
+ return () -> mQueuedRunnables.remove(container);
+ }
+
+ @Override
+ public void execute(Runnable command) {
+ executeDelayed(command, 0);
+ }
+
+ @Override
+ public void removeAll() {
+ mQueuedRunnables.clear();
+ }
+
+ /**
+ * Run all Executors in a loop until they all report they have no ready work to do.
+ *
+ * Useful if you have Executors the post work to other Executors, and you simply want to
+ * run them all until they stop posting work.
+ */
+ public static void exhaustExecutors(FakeExecutor ...executors) {
+ boolean didAnything;
+ do {
+ didAnything = false;
+ for (FakeExecutor executor : executors) {
+ didAnything = didAnything || executor.runAllReady() != 0;
+ }
+ } while (didAnything);
+ }
+
+ private void updateClock(long nextTime) {
+ mIgnoreClockUpdates = true;
+ mClock.setUptimeMillis(nextTime);
+ mIgnoreClockUpdates = false;
+ }
+
+ private static class QueuedRunnable implements Comparable<QueuedRunnable> {
+ private static AtomicInteger sCounter = new AtomicInteger();
+
+ Runnable mRunnable;
+ long mWhen;
+ private int mCounter;
+
+ private QueuedRunnable(Runnable r, long when) {
+ mRunnable = r;
+ mWhen = when;
+
+ // PrioirityQueue orders items arbitrarily when equal. We want to ensure that
+ // otherwise-equal elements are ordered according to their insertion order. Because this
+ // class only is constructed right before insertion, we use a static counter to track
+ // insertion order of otherwise equal elements.
+ mCounter = sCounter.incrementAndGet();
+ }
+
+ @Override
+ public int compareTo(QueuedRunnable other) {
+ long diff = mWhen - other.mWhen;
+
+ if (diff == 0) {
+ return mCounter - other.mCounter;
+ }
+
+ return diff > 0 ? 1 : -1;
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutorTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutorTest.java
new file mode 100644
index 0000000..7fd69424
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeExecutorTest.java
@@ -0,0 +1,366 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import kotlin.jvm.functions.Function4;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class FakeExecutorTest extends SysuiTestCase {
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ /**
+ * Test FakeExecutor that receives non-delayed items to execute.
+ */
+ @Test
+ public void testNoDelay() {
+ FakeSystemClock clock = new FakeSystemClock();
+ clock.setAutoIncrement(false);
+ FakeExecutor fakeExecutor = new FakeExecutor(clock);
+ RunnableImpl runnable = new RunnableImpl();
+
+ assertEquals(0, clock.uptimeMillis());
+ assertEquals(0, runnable.mRunCount);
+
+ // Execute two runnables. They should not run and should be left pending.
+ fakeExecutor.execute(runnable);
+ assertEquals(0, runnable.mRunCount);
+ assertEquals(0, clock.uptimeMillis());
+ assertEquals(1, fakeExecutor.numPending());
+ fakeExecutor.execute(runnable);
+ assertEquals(0, runnable.mRunCount);
+ assertEquals(0, clock.uptimeMillis());
+ assertEquals(2, fakeExecutor.numPending());
+
+ // Run one pending runnable.
+ assertTrue(fakeExecutor.runNextReady());
+ assertEquals(1, runnable.mRunCount);
+ assertEquals(0, clock.uptimeMillis());
+ assertEquals(1, fakeExecutor.numPending());
+ // Run a second pending runnable.
+ assertTrue(fakeExecutor.runNextReady());
+ assertEquals(2, runnable.mRunCount);
+ assertEquals(0, clock.uptimeMillis());
+ assertEquals(0, fakeExecutor.numPending());
+
+ // No more runnables to run.
+ assertFalse(fakeExecutor.runNextReady());
+
+ // Add two more runnables.
+ fakeExecutor.execute(runnable);
+ fakeExecutor.execute(runnable);
+ assertEquals(2, runnable.mRunCount);
+ assertEquals(0, clock.uptimeMillis());
+ assertEquals(2, fakeExecutor.numPending());
+ // Execute all pending runnables in batch.
+ assertEquals(2, fakeExecutor.runAllReady());
+ assertEquals(4, runnable.mRunCount);
+ assertEquals(0, clock.uptimeMillis());
+ assertEquals(0, fakeExecutor.runAllReady());
+ }
+
+ /**
+ * Test FakeExecutor that is told to delay execution on items.
+ */
+ @Test
+ public void testDelayed() {
+ FakeSystemClock clock = new FakeSystemClock();
+ clock.setAutoIncrement(false);
+ FakeExecutor fakeExecutor = new FakeExecutor(clock);
+ RunnableImpl runnable = new RunnableImpl();
+
+ // Add three delayed runnables.
+ fakeExecutor.executeDelayed(runnable, 1);
+ fakeExecutor.executeDelayed(runnable, 50);
+ fakeExecutor.executeDelayed(runnable, 100);
+ assertEquals(0, runnable.mRunCount);
+ assertEquals(0, clock.uptimeMillis());
+ assertEquals(3, fakeExecutor.numPending());
+ // Delayed runnables should not advance the clock and therefore should not run.
+ assertFalse(fakeExecutor.runNextReady());
+ assertEquals(0, fakeExecutor.runAllReady());
+ assertEquals(3, fakeExecutor.numPending());
+
+ // Advance the clock to the next runnable. One runnable should execute.
+ assertEquals(1, fakeExecutor.advanceClockToNext());
+ assertEquals(1, fakeExecutor.runAllReady());
+ assertEquals(2, fakeExecutor.numPending());
+ assertEquals(1, runnable.mRunCount);
+ // Advance the clock to the last runnable.
+ assertEquals(99, fakeExecutor.advanceClockToLast());
+ assertEquals(2, fakeExecutor.runAllReady());
+ // Now all remaining runnables should execute.
+ assertEquals(0, fakeExecutor.numPending());
+ assertEquals(3, runnable.mRunCount);
+ }
+
+ /**
+ * Test FakeExecutor that is told to delay execution on items.
+ */
+ @Test
+ public void testDelayed_AdvanceAndRun() {
+ FakeSystemClock clock = new FakeSystemClock();
+ clock.setAutoIncrement(false);
+ FakeExecutor fakeExecutor = new FakeExecutor(clock);
+ RunnableImpl runnable = new RunnableImpl();
+
+ // Add three delayed runnables.
+ fakeExecutor.executeDelayed(runnable, 1);
+ fakeExecutor.executeDelayed(runnable, 50);
+ fakeExecutor.executeDelayed(runnable, 100);
+ assertEquals(0, runnable.mRunCount);
+ assertEquals(0, clock.uptimeMillis());
+ assertEquals(3, fakeExecutor.numPending());
+ // Delayed runnables should not advance the clock and therefore should not run.
+ assertFalse(fakeExecutor.runNextReady());
+ assertEquals(0, fakeExecutor.runAllReady());
+ assertEquals(3, fakeExecutor.numPending());
+
+ // Advance the clock to the next runnable. Check that it is run.
+ assertEquals(1, fakeExecutor.advanceClockToNext());
+ assertEquals(1, fakeExecutor.runAllReady());
+ assertEquals(1, clock.uptimeMillis());
+ assertEquals(2, fakeExecutor.numPending());
+ assertEquals(1, runnable.mRunCount);
+ assertEquals(49, fakeExecutor.advanceClockToNext());
+ assertEquals(1, fakeExecutor.runAllReady());
+ assertEquals(50, clock.uptimeMillis());
+ assertEquals(1, fakeExecutor.numPending());
+ assertEquals(2, runnable.mRunCount);
+ assertEquals(50, fakeExecutor.advanceClockToNext());
+ assertEquals(1, fakeExecutor.runAllReady());
+ assertEquals(100, clock.uptimeMillis());
+ assertEquals(0, fakeExecutor.numPending());
+ assertEquals(3, runnable.mRunCount);
+
+ // Nothing left to do
+ assertEquals(0, fakeExecutor.advanceClockToNext());
+ assertEquals(0, fakeExecutor.runAllReady());
+ assertEquals(100, clock.uptimeMillis());
+ assertEquals(0, fakeExecutor.numPending());
+ assertEquals(3, runnable.mRunCount);
+ }
+
+ /**
+ * Test execution order.
+ */
+ @Test
+ public void testExecutionOrder() {
+ FakeSystemClock clock = new FakeSystemClock();
+ clock.setAutoIncrement(false);
+ FakeExecutor fakeExecutor = new FakeExecutor(clock);
+ RunnableImpl runnableA = new RunnableImpl();
+ RunnableImpl runnableB = new RunnableImpl();
+ RunnableImpl runnableC = new RunnableImpl();
+ RunnableImpl runnableD = new RunnableImpl();
+
+ Function4<Integer, Integer, Integer, Integer, Void> checkRunCounts =
+ (Integer argA, Integer argB, Integer argC, Integer argD) -> {
+ assertEquals("RunnableA run count wrong", argA.intValue(), runnableA.mRunCount);
+ assertEquals("RunnableB run count wrong", argB.intValue(), runnableB.mRunCount);
+ assertEquals("RunnableC run count wrong", argC.intValue(), runnableC.mRunCount);
+ assertEquals("RunnableD run count wrong", argD.intValue(), runnableD.mRunCount);
+ return null;
+ };
+
+ assertEquals(0, clock.uptimeMillis());
+ checkRunCounts.invoke(0, 0, 0, 0);
+
+ fakeExecutor.execute(runnableA);
+ fakeExecutor.execute(runnableB);
+ fakeExecutor.execute(runnableC);
+ fakeExecutor.execute(runnableD);
+
+ fakeExecutor.runNextReady();
+ checkRunCounts.invoke(1, 0, 0, 0);
+ fakeExecutor.runNextReady();
+ checkRunCounts.invoke(1, 1, 0, 0);
+ fakeExecutor.runNextReady();
+ checkRunCounts.invoke(1, 1, 1, 0);
+ fakeExecutor.runNextReady();
+ checkRunCounts.invoke(1, 1, 1, 1);
+
+ fakeExecutor.executeDelayed(runnableA, 100);
+ fakeExecutor.execute(runnableB);
+ fakeExecutor.executeDelayed(runnableC, 50);
+ fakeExecutor.execute(runnableD);
+
+ fakeExecutor.advanceClockToNext();
+ fakeExecutor.runAllReady();
+ checkRunCounts.invoke(1, 2, 1, 2);
+ fakeExecutor.advanceClockToNext();
+ fakeExecutor.runAllReady();
+ checkRunCounts.invoke(1, 2, 2, 2);
+ fakeExecutor.advanceClockToNext();
+ fakeExecutor.runAllReady();
+ checkRunCounts.invoke(2, 2, 2, 2);
+
+ fakeExecutor.execute(runnableA);
+ fakeExecutor.executeAtTime(runnableB, 0); // this is in the past!
+ fakeExecutor.executeAtTime(runnableC, 1000);
+ fakeExecutor.executeAtTime(runnableD, 500);
+
+ fakeExecutor.advanceClockToNext();
+ fakeExecutor.runAllReady();
+ checkRunCounts.invoke(3, 3, 2, 2);
+ fakeExecutor.advanceClockToNext();
+ fakeExecutor.runAllReady();
+ checkRunCounts.invoke(3, 3, 2, 3);
+ fakeExecutor.advanceClockToNext();
+ fakeExecutor.runAllReady();
+ checkRunCounts.invoke(3, 3, 3, 3);
+ }
+
+ /**
+ * Test removing a single item.
+ */
+ @Test
+ public void testRemoval_single() {
+ FakeSystemClock clock = new FakeSystemClock();
+ clock.setAutoIncrement(false);
+ FakeExecutor fakeExecutor = new FakeExecutor(clock);
+ RunnableImpl runnable = new RunnableImpl();
+ Runnable removeFunction;
+
+ // Nothing to remove.
+ assertEquals(0, runnable.mRunCount);
+ assertEquals(0, fakeExecutor.numPending());
+
+ // Two pending items that have not yet run.
+ // We will try to remove the second item.
+ fakeExecutor.executeDelayed(runnable, 100);
+ removeFunction = fakeExecutor.executeDelayed(runnable, 200);
+ assertEquals(2, fakeExecutor.numPending());
+ assertEquals(0, runnable.mRunCount);
+
+ // Remove the item.
+ removeFunction.run();
+ assertEquals(1, fakeExecutor.numPending());
+ assertEquals(0, runnable.mRunCount);
+
+ // One item to run.
+ fakeExecutor.advanceClockToLast();
+ fakeExecutor.runAllReady();
+ assertEquals(0, fakeExecutor.numPending());
+ assertEquals(1, runnable.mRunCount);
+
+ // Nothing to remove.
+ removeFunction.run();
+ fakeExecutor.runAllReady();
+ assertEquals(0, fakeExecutor.numPending());
+ assertEquals(1, runnable.mRunCount);
+ }
+
+ /**
+ * Test removing multiple items.
+ */
+ @Test
+ public void testRemoval_multi() {
+ FakeSystemClock clock = new FakeSystemClock();
+ clock.setAutoIncrement(false);
+ FakeExecutor fakeExecutor = new FakeExecutor(clock);
+ List<Runnable> removeFunctions = new ArrayList<>();
+ RunnableImpl runnable = new RunnableImpl();
+
+ // Nothing to remove.
+ assertEquals(0, runnable.mRunCount);
+ assertEquals(0, fakeExecutor.numPending());
+
+ // Three pending items that have not yet run.
+ // We will try to remove the first and third items.
+ removeFunctions.add(fakeExecutor.executeDelayed(runnable, 100));
+ fakeExecutor.executeDelayed(runnable, 200);
+ removeFunctions.add(fakeExecutor.executeDelayed(runnable, 300));
+ assertEquals(3, fakeExecutor.numPending());
+ assertEquals(0, runnable.mRunCount);
+
+ // Remove the items.
+ removeFunctions.forEach(Runnable::run);
+ assertEquals(1, fakeExecutor.numPending());
+ assertEquals(0, runnable.mRunCount);
+
+ // One item to run.
+ fakeExecutor.advanceClockToLast();
+ fakeExecutor.runAllReady();
+ assertEquals(0, fakeExecutor.numPending());
+ assertEquals(1, runnable.mRunCount);
+
+ // Nothing to remove.
+ removeFunctions.forEach(Runnable::run);
+ assertEquals(0, fakeExecutor.numPending());
+ assertEquals(1, runnable.mRunCount);
+ }
+
+ /**
+ * Test removing everything
+ */
+ @Test
+ public void testRemoval_all() {
+ FakeSystemClock clock = new FakeSystemClock();
+ clock.setAutoIncrement(false);
+ FakeExecutor fakeExecutor = new FakeExecutor(clock);
+ RunnableImpl runnable = new RunnableImpl();
+
+ // Nothing to remove.
+ assertEquals(0, runnable.mRunCount);
+ assertEquals(0, fakeExecutor.numPending());
+
+ // Two pending items that have not yet run.
+ fakeExecutor.executeDelayed(runnable, 100);
+ fakeExecutor.executeDelayed(runnable, 200);
+ assertEquals(2, fakeExecutor.numPending());
+ assertEquals(0, runnable.mRunCount);
+
+ // Remove the items.
+ fakeExecutor.removeAll();
+
+ // Nothing to run
+ fakeExecutor.advanceClockToLast();
+ assertEquals(0, fakeExecutor.runAllReady());
+ assertEquals(0, fakeExecutor.numPending());
+ assertEquals(0, runnable.mRunCount);
+ }
+
+ private static class RunnableImpl implements Runnable {
+ int mRunCount;
+
+ @Override
+ public void run() {
+ mRunCount++;
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java b/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java
index 7b5417c..65e5902 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/time/FakeSystemClock.java
@@ -16,6 +16,9 @@
package com.android.systemui.util.time;
+import java.util.ArrayList;
+import java.util.List;
+
public class FakeSystemClock implements SystemClock {
private boolean mAutoIncrement = true;
@@ -26,11 +29,13 @@
private long mCurrentThreadTimeMicro;
private long mCurrentTimeMicro;
+ List<ClockTickListener> mListeners = new ArrayList<>();
+
@Override
public long uptimeMillis() {
long value = mUptimeMillis;
if (mAutoIncrement) {
- mUptimeMillis++;
+ setUptimeMillis(mUptimeMillis + 1);
}
return value;
}
@@ -39,7 +44,7 @@
public long elapsedRealtime() {
long value = mElapsedRealtime;
if (mAutoIncrement) {
- mElapsedRealtime++;
+ setElapsedRealtime(mElapsedRealtime + 1);
}
return value;
}
@@ -48,7 +53,7 @@
public long elapsedRealtimeNanos() {
long value = mElapsedRealtimeNanos;
if (mAutoIncrement) {
- mElapsedRealtimeNanos++;
+ setElapsedRealtimeNanos(mElapsedRealtimeNanos + 1);
}
return value;
}
@@ -57,7 +62,7 @@
public long currentThreadTimeMillis() {
long value = mCurrentThreadTimeMillis;
if (mAutoIncrement) {
- mCurrentThreadTimeMillis++;
+ setCurrentThreadTimeMillis(mCurrentThreadTimeMillis + 1);
}
return value;
}
@@ -66,7 +71,7 @@
public long currentThreadTimeMicro() {
long value = mCurrentThreadTimeMicro;
if (mAutoIncrement) {
- mCurrentThreadTimeMicro++;
+ setCurrentThreadTimeMicro(mCurrentThreadTimeMicro + 1);
}
return value;
}
@@ -75,37 +80,90 @@
public long currentTimeMicro() {
long value = mCurrentTimeMicro;
if (mAutoIncrement) {
- mCurrentTimeMicro++;
+ setCurrentTimeMicro(mCurrentTimeMicro + 1);
}
return value;
}
public void setUptimeMillis(long uptimeMillis) {
mUptimeMillis = uptimeMillis;
+ for (ClockTickListener listener : mListeners) {
+ listener.onUptimeMillis(mUptimeMillis);
+ }
}
public void setElapsedRealtime(long elapsedRealtime) {
mElapsedRealtime = elapsedRealtime;
+ for (ClockTickListener listener : mListeners) {
+ listener.onElapsedRealtime(mElapsedRealtime);
+ }
}
public void setElapsedRealtimeNanos(long elapsedRealtimeNanos) {
mElapsedRealtimeNanos = elapsedRealtimeNanos;
+ for (ClockTickListener listener : mListeners) {
+ listener.onElapsedRealtimeNanos(mElapsedRealtimeNanos);
+ }
}
public void setCurrentThreadTimeMillis(long currentThreadTimeMillis) {
mCurrentThreadTimeMillis = currentThreadTimeMillis;
+ for (ClockTickListener listener : mListeners) {
+ listener.onCurrentThreadTimeMillis(mCurrentThreadTimeMillis);
+ }
}
public void setCurrentThreadTimeMicro(long currentThreadTimeMicro) {
mCurrentThreadTimeMicro = currentThreadTimeMicro;
+ for (ClockTickListener listener : mListeners) {
+ listener.onCurrentThreadTimeMicro(mCurrentThreadTimeMicro);
+ }
}
public void setCurrentTimeMicro(long currentTimeMicro) {
mCurrentTimeMicro = currentTimeMicro;
+ for (ClockTickListener listener : mListeners) {
+ listener.onCurrentTimeMicro(mCurrentTimeMicro);
+ }
}
/** If true, each call to get____ will be one higher than the previous call to that method. */
public void setAutoIncrement(boolean autoIncrement) {
mAutoIncrement = autoIncrement;
}
+
+ public void addListener(ClockTickListener listener) {
+ mListeners.add(listener);
+ }
+
+ public void removeListener(ClockTickListener listener) {
+ mListeners.remove(listener);
+ }
+
+ /** Alert all the listeners about the current time. */
+ public void synchronizeListeners() {
+ for (ClockTickListener listener : mListeners) {
+ listener.onUptimeMillis(mUptimeMillis);
+ listener.onElapsedRealtime(mElapsedRealtime);
+ listener.onElapsedRealtimeNanos(mElapsedRealtimeNanos);
+ listener.onCurrentThreadTimeMillis(mCurrentThreadTimeMillis);
+ listener.onCurrentThreadTimeMicro(mCurrentThreadTimeMicro);
+ listener.onCurrentTimeMicro(mCurrentTimeMicro);
+ }
+ }
+
+
+ public interface ClockTickListener {
+ default void onUptimeMillis(long uptimeMillis) {}
+
+ default void onElapsedRealtime(long elapsedRealtime) {}
+
+ default void onElapsedRealtimeNanos(long elapsedRealtimeNanos) {}
+
+ default void onCurrentThreadTimeMillis(long currentThreadTimeMillis) {}
+
+ default void onCurrentThreadTimeMicro(long currentThreadTimeMicro) {}
+
+ default void onCurrentTimeMicro(long currentTimeMicro) {}
+ }
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index 339fc96..8ce92a3 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -972,6 +972,9 @@
if (shouldComputeWindows) {
mWindowManagerInternal.computeWindowsForAccessibility(displayId);
}
+
+ mWindowManagerInternal.setAccessibilityIdToSurfaceMetadata(
+ windowToken.asBinder(), windowId);
return windowId;
}
@@ -991,7 +994,7 @@
final int removedWindowId = removeAccessibilityInteractionConnectionInternalLocked(
token, mGlobalWindowTokens, mGlobalInteractionConnections);
if (removedWindowId >= 0) {
- onAccessibilityInteractionConnectionRemovedLocked(removedWindowId);
+ onAccessibilityInteractionConnectionRemovedLocked(removedWindowId, token);
if (DEBUG) {
Slog.i(LOG_TAG, "Removed global connection for pid:" + Binder.getCallingPid()
+ " with windowId: " + removedWindowId + " and token: "
@@ -1007,7 +1010,8 @@
getWindowTokensForUserLocked(userId),
getInteractionConnectionsForUserLocked(userId));
if (removedWindowIdForUser >= 0) {
- onAccessibilityInteractionConnectionRemovedLocked(removedWindowIdForUser);
+ onAccessibilityInteractionConnectionRemovedLocked(
+ removedWindowIdForUser, token);
if (DEBUG) {
Slog.i(LOG_TAG, "Removed user connection for pid:" + Binder.getCallingPid()
+ " with windowId: " + removedWindowIdForUser + " and userId:"
@@ -1069,18 +1073,21 @@
* @param userId The userId to remove
*/
private void removeAccessibilityInteractionConnectionLocked(int windowId, int userId) {
+ IBinder window = null;
if (userId == UserHandle.USER_ALL) {
+ window = mGlobalWindowTokens.get(windowId);
mGlobalWindowTokens.remove(windowId);
mGlobalInteractionConnections.remove(windowId);
} else {
if (isValidUserForWindowTokensLocked(userId)) {
+ window = getWindowTokensForUserLocked(userId).get(windowId);
getWindowTokensForUserLocked(userId).remove(windowId);
}
if (isValidUserForInteractionConnectionsLocked(userId)) {
getInteractionConnectionsForUserLocked(userId).remove(windowId);
}
}
- onAccessibilityInteractionConnectionRemovedLocked(windowId);
+ onAccessibilityInteractionConnectionRemovedLocked(windowId, window);
if (DEBUG) {
Slog.i(LOG_TAG, "Removing interaction connection to windowId: " + windowId);
}
@@ -1091,12 +1098,17 @@
*
* @param windowId Removed windowId
*/
- private void onAccessibilityInteractionConnectionRemovedLocked(int windowId) {
+ private void onAccessibilityInteractionConnectionRemovedLocked(
+ int windowId, @Nullable IBinder binder) {
// Active window will not update, if windows callback is unregistered.
// Update active window to invalid, when its a11y interaction connection is removed.
if (!isTrackingWindowsLocked() && windowId >= 0 && mActiveWindowId == windowId) {
mActiveWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
}
+ if (binder != null) {
+ mWindowManagerInternal.setAccessibilityIdToSurfaceMetadata(
+ binder, AccessibilityWindowInfo.UNDEFINED_WINDOW_ID);
+ }
}
/**
diff --git a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
index 19ac0d3..1754926 100644
--- a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
+++ b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
@@ -17,6 +17,8 @@
package com.android.server.accessibility;
import android.accessibilityservice.AccessibilityService;
+import android.app.PendingIntent;
+import android.app.RemoteAction;
import android.app.StatusBarManager;
import android.content.Context;
import android.hardware.input.InputManager;
@@ -25,81 +27,272 @@
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.util.ArrayMap;
+import android.util.Slog;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ScreenshotHelper;
import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.WindowManagerInternal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
import java.util.function.Supplier;
/**
- * Handle the back-end of AccessibilityService#performGlobalAction
+ * Handle the back-end of system AccessibilityAction.
+ *
+ * This class should support three use cases with combined usage of new API and legacy API:
+ *
+ * Use case 1: SystemUI doesn't use the new system action registration API. Accessibility
+ * service doesn't use the new system action API to obtain action list. Accessibility
+ * service uses legacy global action id to perform predefined system actions.
+ * Use case 2: SystemUI uses the new system action registration API to register available system
+ * actions. Accessibility service doesn't use the new system action API to obtain action
+ * list. Accessibility service uses legacy global action id to trigger the system
+ * actions registered by SystemUI.
+ * Use case 3: SystemUI doesn't use the new system action registration API.Accessibility service
+ * obtains the available system actions using new AccessibilityService API and trigger
+ * the predefined system actions.
*/
public class SystemActionPerformer {
+ private static final String TAG = "SystemActionPerformer";
+
+ interface SystemActionsChangedListener {
+ void onSystemActionsChanged();
+ }
+ private final SystemActionsChangedListener mListener;
+
+ private final Object mSystemActionLock = new Object();
+ // Resource id based ActionId -> RemoteAction
+ @GuardedBy("mSystemActionLock")
+ private final Map<Integer, RemoteAction> mRegisteredSystemActions = new ArrayMap<>();
+
+ // Legacy system actions.
+ private final AccessibilityAction mLegacyHomeAction;
+ private final AccessibilityAction mLegacyBackAction;
+ private final AccessibilityAction mLegacyRecentsAction;
+ private final AccessibilityAction mLegacyNotificationsAction;
+ private final AccessibilityAction mLegacyQuickSettingsAction;
+ private final AccessibilityAction mLegacyPowerDialogAction;
+ private final AccessibilityAction mLegacyToggleSplitScreenAction;
+ private final AccessibilityAction mLegacyLockScreenAction;
+ private final AccessibilityAction mLegacyTakeScreenshotAction;
+
private final WindowManagerInternal mWindowManagerService;
private final Context mContext;
private Supplier<ScreenshotHelper> mScreenshotHelperSupplier;
- public SystemActionPerformer(Context context, WindowManagerInternal windowManagerInternal) {
- mContext = context;
- mWindowManagerService = windowManagerInternal;
- mScreenshotHelperSupplier = null;
+ public SystemActionPerformer(
+ Context context,
+ WindowManagerInternal windowManagerInternal) {
+ this(context, windowManagerInternal, null, null);
}
// Used to mock ScreenshotHelper
@VisibleForTesting
- public SystemActionPerformer(Context context, WindowManagerInternal windowManagerInternal,
+ public SystemActionPerformer(
+ Context context,
+ WindowManagerInternal windowManagerInternal,
Supplier<ScreenshotHelper> screenshotHelperSupplier) {
- this(context, windowManagerInternal);
+ this(context, windowManagerInternal, screenshotHelperSupplier, null);
+ }
+
+ public SystemActionPerformer(
+ Context context,
+ WindowManagerInternal windowManagerInternal,
+ Supplier<ScreenshotHelper> screenshotHelperSupplier,
+ SystemActionsChangedListener listener) {
+ mContext = context;
+ mWindowManagerService = windowManagerInternal;
+ mListener = listener;
mScreenshotHelperSupplier = screenshotHelperSupplier;
+
+ mLegacyHomeAction = new AccessibilityAction(
+ AccessibilityService.GLOBAL_ACTION_HOME,
+ mContext.getResources().getString(
+ R.string.accessibility_system_action_home_label));
+ mLegacyBackAction = new AccessibilityAction(
+ AccessibilityService.GLOBAL_ACTION_BACK,
+ mContext.getResources().getString(
+ R.string.accessibility_system_action_back_label));
+ mLegacyRecentsAction = new AccessibilityAction(
+ AccessibilityService.GLOBAL_ACTION_RECENTS,
+ mContext.getResources().getString(
+ R.string.accessibility_system_action_recents_label));
+ mLegacyNotificationsAction = new AccessibilityAction(
+ AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS,
+ mContext.getResources().getString(
+ R.string.accessibility_system_action_notifications_label));
+ mLegacyQuickSettingsAction = new AccessibilityAction(
+ AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS,
+ mContext.getResources().getString(
+ R.string.accessibility_system_action_quick_settings_label));
+ mLegacyPowerDialogAction = new AccessibilityAction(
+ AccessibilityService.GLOBAL_ACTION_POWER_DIALOG,
+ mContext.getResources().getString(
+ R.string.accessibility_system_action_power_dialog_label));
+ mLegacyToggleSplitScreenAction = new AccessibilityAction(
+ AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN,
+ mContext.getResources().getString(
+ R.string.accessibility_system_action_toggle_split_screen_label));
+ mLegacyLockScreenAction = new AccessibilityAction(
+ AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN,
+ mContext.getResources().getString(
+ R.string.accessibility_system_action_lock_screen_label));
+ mLegacyTakeScreenshotAction = new AccessibilityAction(
+ AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT,
+ mContext.getResources().getString(
+ R.string.accessibility_system_action_screenshot_label));
}
/**
- * Performe the system action matching the given action id.
+ * This method is called to register a system action. If a system action is already registered
+ * with the given id, the existing system action will be overwritten.
*/
- public boolean performSystemAction(int action) {
+ void registerSystemAction(int id, RemoteAction action) {
+ synchronized (mSystemActionLock) {
+ mRegisteredSystemActions.put(id, action);
+ }
+ if (mListener != null) {
+ mListener.onSystemActionsChanged();
+ }
+ }
+
+ /**
+ * This method is called to unregister a system action previously registered through
+ * registerSystemAction.
+ */
+ void unregisterSystemAction(int id) {
+ synchronized (mSystemActionLock) {
+ mRegisteredSystemActions.remove(id);
+ }
+ if (mListener != null) {
+ mListener.onSystemActionsChanged();
+ }
+ }
+
+ /**
+ * This method returns the list of available system actions.
+ */
+ List<AccessibilityAction> getSystemActions() {
+ List<AccessibilityAction> systemActions = new ArrayList<>();
+ synchronized (mSystemActionLock) {
+ for (Map.Entry<Integer, RemoteAction> entry : mRegisteredSystemActions.entrySet()) {
+ AccessibilityAction systemAction = new AccessibilityAction(
+ entry.getKey(),
+ entry.getValue().getTitle());
+ systemActions.add(systemAction);
+ }
+
+ // add AccessibilitySystemAction entry for legacy system actions if not overwritten
+ addLegacySystemActions(systemActions);
+ }
+ return systemActions;
+ }
+
+ private void addLegacySystemActions(List<AccessibilityAction> systemActions) {
+ if (!mRegisteredSystemActions.containsKey(AccessibilityService.GLOBAL_ACTION_BACK)) {
+ systemActions.add(mLegacyBackAction);
+ }
+ if (!mRegisteredSystemActions.containsKey(AccessibilityService.GLOBAL_ACTION_HOME)) {
+ systemActions.add(mLegacyHomeAction);
+ }
+ if (!mRegisteredSystemActions.containsKey(AccessibilityService.GLOBAL_ACTION_RECENTS)) {
+ systemActions.add(mLegacyRecentsAction);
+ }
+ if (!mRegisteredSystemActions.containsKey(
+ AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS)) {
+ systemActions.add(mLegacyNotificationsAction);
+ }
+ if (!mRegisteredSystemActions.containsKey(
+ AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS)) {
+ systemActions.add(mLegacyQuickSettingsAction);
+ }
+ if (!mRegisteredSystemActions.containsKey(
+ AccessibilityService.GLOBAL_ACTION_POWER_DIALOG)) {
+ systemActions.add(mLegacyPowerDialogAction);
+ }
+ if (!mRegisteredSystemActions.containsKey(
+ AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN)) {
+ systemActions.add(mLegacyToggleSplitScreenAction);
+ }
+ if (!mRegisteredSystemActions.containsKey(
+ AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN)) {
+ systemActions.add(mLegacyLockScreenAction);
+ }
+ if (!mRegisteredSystemActions.containsKey(
+ AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT)) {
+ systemActions.add(mLegacyTakeScreenshotAction);
+ }
+ }
+
+ /**
+ * Trigger the registered action by the matching action id.
+ */
+ public boolean performSystemAction(int actionId) {
final long identity = Binder.clearCallingIdentity();
try {
- switch (action) {
- case AccessibilityService.GLOBAL_ACTION_BACK: {
- sendDownAndUpKeyEvents(KeyEvent.KEYCODE_BACK);
- }
- return true;
- case AccessibilityService.GLOBAL_ACTION_HOME: {
- sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HOME);
- }
- return true;
- case AccessibilityService.GLOBAL_ACTION_RECENTS: {
- return openRecents();
- }
- case AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS: {
- expandNotifications();
- }
- return true;
- case AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS: {
- expandQuickSettings();
- }
- return true;
- case AccessibilityService.GLOBAL_ACTION_POWER_DIALOG: {
- showGlobalActions();
- }
- return true;
- case AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN: {
- return toggleSplitScreen();
- }
- case AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN: {
- return lockScreen();
- }
- case AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT: {
- return takeScreenshot();
+ synchronized (mSystemActionLock) {
+ // If a system action is registered with the given actionId, call the corresponding
+ // RemoteAction.
+ RemoteAction registeredAction = mRegisteredSystemActions.get(actionId);
+ if (registeredAction != null) {
+ try {
+ registeredAction.getActionIntent().send();
+ return true;
+ } catch (PendingIntent.CanceledException ex) {
+ Slog.e(TAG,
+ "canceled PendingIntent for global action "
+ + registeredAction.getTitle(),
+ ex);
+ }
+ return false;
}
}
- return false;
+
+ // No RemoteAction registered with the given actionId, try the default legacy system
+ // actions.
+ switch (actionId) {
+ case AccessibilityService.GLOBAL_ACTION_BACK: {
+ sendDownAndUpKeyEvents(KeyEvent.KEYCODE_BACK);
+ return true;
+ }
+ case AccessibilityService.GLOBAL_ACTION_HOME: {
+ sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HOME);
+ return true;
+ }
+ case AccessibilityService.GLOBAL_ACTION_RECENTS:
+ return openRecents();
+ case AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS: {
+ expandNotifications();
+ return true;
+ }
+ case AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS: {
+ expandQuickSettings();
+ return true;
+ }
+ case AccessibilityService.GLOBAL_ACTION_POWER_DIALOG: {
+ showGlobalActions();
+ return true;
+ }
+ case AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN:
+ return toggleSplitScreen();
+ case AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN:
+ return lockScreen();
+ case AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT:
+ return takeScreenshot();
+ default:
+ return false;
+ }
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/android/app/usage/UsageStatsManagerInternal.java b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
index 6641b5b..2f8c506 100644
--- a/services/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -281,4 +281,13 @@
return mUsageRemaining;
}
}
+
+ /**
+ * Called by {@link com.android.server.usage.UsageStatsIdleService} when the device is idle to
+ * prune usage stats data for uninstalled packages.
+ *
+ * @param userId the user associated with the job
+ * @return {@code true} if the pruning was successful, {@code false} otherwise
+ */
+ public abstract boolean pruneUninstalledPackagesData(@UserIdInt int userId);
}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index e4d477a..1e5b915 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -790,7 +790,7 @@
return b.toString();
}
- public void writeToProto(ProtoOutputStream proto, long fieldId, long nowElapsed,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, long nowElapsed,
long nowRTC) {
final long token = proto.start(fieldId);
@@ -798,7 +798,7 @@
proto.write(BatchProto.END_REALTIME, end);
proto.write(BatchProto.FLAGS, flags);
for (Alarm a : alarms) {
- a.writeToProto(proto, BatchProto.ALARMS, nowElapsed, nowRTC);
+ a.dumpDebug(proto, BatchProto.ALARMS, nowElapsed, nowRTC);
}
proto.end(token);
@@ -1320,7 +1320,7 @@
+ "}";
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(InFlightProto.UID, mUid);
@@ -1328,16 +1328,16 @@
proto.write(InFlightProto.WHEN_ELAPSED_MS, mWhenElapsed);
proto.write(InFlightProto.ALARM_TYPE, mAlarmType);
if (mPendingIntent != null) {
- mPendingIntent.writeToProto(proto, InFlightProto.PENDING_INTENT);
+ mPendingIntent.dumpDebug(proto, InFlightProto.PENDING_INTENT);
}
if (mBroadcastStats != null) {
- mBroadcastStats.writeToProto(proto, InFlightProto.BROADCAST_STATS);
+ mBroadcastStats.dumpDebug(proto, InFlightProto.BROADCAST_STATS);
}
if (mFilterStats != null) {
- mFilterStats.writeToProto(proto, InFlightProto.FILTER_STATS);
+ mFilterStats.dumpDebug(proto, InFlightProto.FILTER_STATS);
}
if (mWorkSource != null) {
- mWorkSource.writeToProto(proto, InFlightProto.WORK_SOURCE);
+ mWorkSource.dumpDebug(proto, InFlightProto.WORK_SOURCE);
}
proto.end(token);
@@ -1387,7 +1387,7 @@
+ "}";
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(FilterStatsProto.TAG, mTag);
@@ -1431,7 +1431,7 @@
+ "}";
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(BroadcastStatsProto.UID, mUid);
@@ -2573,34 +2573,34 @@
proto.end(aToken);
}
for (Batch b : mAlarmBatches) {
- b.writeToProto(proto, AlarmManagerServiceDumpProto.PENDING_ALARM_BATCHES,
+ b.dumpDebug(proto, AlarmManagerServiceDumpProto.PENDING_ALARM_BATCHES,
nowElapsed, nowRTC);
}
for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) {
final ArrayList<Alarm> blockedAlarms = mPendingBackgroundAlarms.valueAt(i);
if (blockedAlarms != null) {
for (Alarm a : blockedAlarms) {
- a.writeToProto(proto,
+ a.dumpDebug(proto,
AlarmManagerServiceDumpProto.PENDING_USER_BLOCKED_BACKGROUND_ALARMS,
nowElapsed, nowRTC);
}
}
}
if (mPendingIdleUntil != null) {
- mPendingIdleUntil.writeToProto(
+ mPendingIdleUntil.dumpDebug(
proto, AlarmManagerServiceDumpProto.PENDING_IDLE_UNTIL, nowElapsed, nowRTC);
}
for (Alarm a : mPendingWhileIdleAlarms) {
- a.writeToProto(proto, AlarmManagerServiceDumpProto.PENDING_WHILE_IDLE_ALARMS,
+ a.dumpDebug(proto, AlarmManagerServiceDumpProto.PENDING_WHILE_IDLE_ALARMS,
nowElapsed, nowRTC);
}
if (mNextWakeFromIdle != null) {
- mNextWakeFromIdle.writeToProto(proto, AlarmManagerServiceDumpProto.NEXT_WAKE_FROM_IDLE,
+ mNextWakeFromIdle.dumpDebug(proto, AlarmManagerServiceDumpProto.NEXT_WAKE_FROM_IDLE,
nowElapsed, nowRTC);
}
for (Alarm a : mPendingNonWakeupAlarms) {
- a.writeToProto(proto, AlarmManagerServiceDumpProto.PAST_DUE_NON_WAKEUP_ALARMS,
+ a.dumpDebug(proto, AlarmManagerServiceDumpProto.PAST_DUE_NON_WAKEUP_ALARMS,
nowElapsed, nowRTC);
}
@@ -2617,7 +2617,7 @@
proto.write(AlarmManagerServiceDumpProto.LISTENER_FINISH_COUNT, mListenerFinishCount);
for (InFlight f : mInFlight) {
- f.writeToProto(proto, AlarmManagerServiceDumpProto.OUTSTANDING_DELIVERIES);
+ f.dumpDebug(proto, AlarmManagerServiceDumpProto.OUTSTANDING_DELIVERIES);
}
for (int i = 0; i < mLastAllowWhileIdleDispatch.size(); ++i) {
@@ -2640,7 +2640,7 @@
}
}
- mLog.writeToProto(proto, AlarmManagerServiceDumpProto.RECENT_PROBLEMS);
+ mLog.dumpDebug(proto, AlarmManagerServiceDumpProto.RECENT_PROBLEMS);
final FilterStats[] topFilters = new FilterStats[10];
final Comparator<FilterStats> comparator = new Comparator<FilterStats>() {
@@ -2687,7 +2687,7 @@
proto.write(AlarmManagerServiceDumpProto.TopAlarm.UID, fs.mBroadcastStats.mUid);
proto.write(AlarmManagerServiceDumpProto.TopAlarm.PACKAGE_NAME,
fs.mBroadcastStats.mPackageName);
- fs.writeToProto(proto, AlarmManagerServiceDumpProto.TopAlarm.FILTER);
+ fs.dumpDebug(proto, AlarmManagerServiceDumpProto.TopAlarm.FILTER);
proto.end(token);
}
@@ -2699,7 +2699,7 @@
final long token = proto.start(AlarmManagerServiceDumpProto.ALARM_STATS);
BroadcastStats bs = uidStats.valueAt(ip);
- bs.writeToProto(proto, AlarmManagerServiceDumpProto.AlarmStat.BROADCAST);
+ bs.dumpDebug(proto, AlarmManagerServiceDumpProto.AlarmStat.BROADCAST);
// uidStats is an ArrayMap, which we can't sort.
tmpFilters.clear();
@@ -2708,7 +2708,7 @@
}
Collections.sort(tmpFilters, comparator);
for (FilterStats fs : tmpFilters) {
- fs.writeToProto(proto, AlarmManagerServiceDumpProto.AlarmStat.FILTERS);
+ fs.dumpDebug(proto, AlarmManagerServiceDumpProto.AlarmStat.FILTERS);
}
proto.end(token);
@@ -3652,7 +3652,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId, long nowElapsed,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, long nowElapsed,
long nowRTC) {
final long token = proto.start(fieldId);
@@ -3664,10 +3664,10 @@
proto.write(AlarmProto.COUNT, count);
proto.write(AlarmProto.FLAGS, flags);
if (alarmClock != null) {
- alarmClock.writeToProto(proto, AlarmProto.ALARM_CLOCK);
+ alarmClock.dumpDebug(proto, AlarmProto.ALARM_CLOCK);
}
if (operation != null) {
- operation.writeToProto(proto, AlarmProto.OPERATION);
+ operation.dumpDebug(proto, AlarmProto.OPERATION);
}
if (listener != null) {
proto.write(AlarmProto.LISTENER, listener.asBinder().toString());
diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java
index 80fda19..deb94bd 100644
--- a/services/core/java/com/android/server/IntentResolver.java
+++ b/services/core/java/com/android/server/IntentResolver.java
@@ -294,7 +294,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
writeProtoMap(proto, IntentResolverProto.FULL_MIME_TYPES, mTypeToFilter);
writeProtoMap(proto, IntentResolverProto.BASE_MIME_TYPES, mBaseTypeToFilter);
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index a9c38bc..76e0c13 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -4,3 +4,6 @@
# Vibrator / Threads
per-file VibratorService.java, DisplayThread.java = michaelwr@google.com
per-file VibratorService.java, DisplayThread.java = ogunwale@google.com
+
+# Zram writeback
+per-file ZramWriteback.java = minchan@google.com, rajekumar@google.com, srnvs@google.com
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 2915257..12debbf 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -42,6 +42,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.XmlUtils;
import libcore.io.IoUtils;
@@ -817,6 +818,21 @@
}
}
+ /** Dump status of every observer in mAllObservers. */
+ public void dump(IndentingPrintWriter pw) {
+ pw.println("Package Watchdog status");
+ pw.increaseIndent();
+ synchronized (mLock) {
+ for (String observerName : mAllObservers.keySet()) {
+ pw.println("Observer name: " + observerName);
+ pw.increaseIndent();
+ ObserverInternal observerInternal = mAllObservers.get(observerName);
+ observerInternal.dump(pw);
+ pw.decreaseIndent();
+ }
+ }
+ }
+
/**
* Represents an observer monitoring a set of packages along with the failure thresholds for
* each package.
@@ -959,6 +975,22 @@
}
return new ObserverInternal(observerName, packages);
}
+
+ /** Dumps information about this observer and the packages it watches. */
+ public void dump(IndentingPrintWriter pw) {
+ boolean isPersistent = registeredObserver != null && registeredObserver.isPersistent();
+ pw.println("Persistent: " + isPersistent);
+ for (String packageName : packages.keySet()) {
+ MonitoredPackage p = packages.get(packageName);
+ pw.println(packageName + ": ");
+ pw.increaseIndent();
+ pw.println("# Failures: " + p.mFailureHistory.size());
+ pw.println("Monitoring duration remaining: " + p.mDurationMs + "ms");
+ pw.println("Explicit health check duration: " + p.mHealthCheckDurationMs + "ms");
+ pw.println("Health check state: " + p.toString(p.mHealthCheckState));
+ pw.decreaseIndent();
+ }
+ }
}
@Retention(SOURCE)
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index d5f7956..135f6f3 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -45,6 +45,7 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.DeviceConfig;
import android.provider.MediaStore;
import android.provider.Settings;
import android.system.ErrnoException;
@@ -97,9 +98,12 @@
private static final int KEY_HOME = 1;
private static final int KEY_ASSISTANT = 2;
- // Pin the camera application.
- private static boolean PROP_PIN_CAMERA = SystemProperties.getBoolean(
- "pinner.pin_camera", true);
+ // Pin the camera application. Default to the system property only if the experiment phenotype
+ // property is not set.
+ private static boolean PROP_PIN_CAMERA =
+ DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT,
+ "pin_camera",
+ SystemProperties.getBoolean("pinner.pin_camera", true));
// Pin using pinlist.meta when pinning apps.
private static boolean PROP_PIN_PINLIST = SystemProperties.getBoolean(
"pinner.use_pinlist", true);
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 9875f6d..1f7d9ea 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -17,6 +17,8 @@
package com.android.server;
import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED;
+import static android.telephony.TelephonyRegistryManager.SIM_ACTIVATION_TYPE_DATA;
+import static android.telephony.TelephonyRegistryManager.SIM_ACTIVATION_TYPE_VOICE;
import static java.util.Arrays.copyOf;
@@ -1201,10 +1203,10 @@
synchronized (mRecords) {
if (validatePhoneId(phoneId)) {
switch (activationType) {
- case TelephonyManager.SIM_ACTIVATION_TYPE_VOICE:
+ case SIM_ACTIVATION_TYPE_VOICE:
mVoiceActivationState[phoneId] = activationState;
break;
- case TelephonyManager.SIM_ACTIVATION_TYPE_DATA:
+ case SIM_ACTIVATION_TYPE_DATA:
mDataActivationState[phoneId] = activationState;
break;
default:
@@ -1217,10 +1219,10 @@
+ " state=" + activationState);
}
try {
- if ((activationType == TelephonyManager.SIM_ACTIVATION_TYPE_VOICE) &&
- r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) &&
- idMatch(r.subId, subId, phoneId)) {
+ if ((activationType == SIM_ACTIVATION_TYPE_VOICE)
+ && r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE)
+ && idMatch(r.subId, subId, phoneId)) {
if (DBG) {
log("notifyVoiceActivationStateForPhoneId: callback.onVASC r=" + r
+ " subId=" + subId + " phoneId=" + phoneId
@@ -1228,10 +1230,10 @@
}
r.callback.onVoiceActivationStateChanged(activationState);
}
- if ((activationType == TelephonyManager.SIM_ACTIVATION_TYPE_DATA) &&
- r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) &&
- idMatch(r.subId, subId, phoneId)) {
+ if ((activationType == SIM_ACTIVATION_TYPE_DATA)
+ && r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE)
+ && idMatch(r.subId, subId, phoneId)) {
if (DBG) {
log("notifyDataActivationStateForPhoneId: callback.onDASC r=" + r
+ " subId=" + subId + " phoneId=" + phoneId
diff --git a/services/core/java/com/android/server/am/ActiveInstrumentation.java b/services/core/java/com/android/server/am/ActiveInstrumentation.java
index 9510f59..b2c82f0 100644
--- a/services/core/java/com/android/server/am/ActiveInstrumentation.java
+++ b/services/core/java/com/android/server/am/ActiveInstrumentation.java
@@ -126,26 +126,26 @@
pw.println(mArguments);
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
- mClass.writeToProto(proto, ActiveInstrumentationProto.CLASS);
+ mClass.dumpDebug(proto, ActiveInstrumentationProto.CLASS);
proto.write(ActiveInstrumentationProto.FINISHED, mFinished);
for (int i=0; i<mRunningProcesses.size(); i++) {
- mRunningProcesses.get(i).writeToProto(proto,
+ mRunningProcesses.get(i).dumpDebug(proto,
ActiveInstrumentationProto.RUNNING_PROCESSES);
}
for (String p : mTargetProcesses) {
proto.write(ActiveInstrumentationProto.TARGET_PROCESSES, p);
}
if (mTargetInfo != null) {
- mTargetInfo.writeToProto(proto, ActiveInstrumentationProto.TARGET_INFO, 0);
+ mTargetInfo.dumpDebug(proto, ActiveInstrumentationProto.TARGET_INFO, 0);
}
proto.write(ActiveInstrumentationProto.PROFILE_FILE, mProfileFile);
proto.write(ActiveInstrumentationProto.WATCHER, mWatcher.toString());
proto.write(ActiveInstrumentationProto.UI_AUTOMATION_CONNECTION,
mUiAutomationConnection.toString());
if (mArguments != null) {
- mArguments.writeToProto(proto, ActiveInstrumentationProto.ARGUMENTS);
+ mArguments.dumpDebug(proto, ActiveInstrumentationProto.ARGUMENTS);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index eb77fea..dab928a 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -4407,7 +4407,7 @@
return new ServiceDumper(fd, pw, args, opti, dumpAll, dumpPackage);
}
- protected void writeToProto(ProtoOutputStream proto, long fieldId) {
+ protected void dumpDebug(ProtoOutputStream proto, long fieldId) {
synchronized (mAm) {
final long outterToken = proto.start(fieldId);
int[] users = mAm.mUserController.getUsers();
@@ -4420,7 +4420,7 @@
proto.write(ActiveServicesProto.ServicesByUser.USER_ID, user);
ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByInstanceName;
for (int i=0; i<alls.size(); i++) {
- alls.valueAt(i).writeToProto(proto,
+ alls.valueAt(i).dumpDebug(proto,
ActiveServicesProto.ServicesByUser.SERVICE_RECORDS);
}
proto.end(token);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 53a5fc6..b191338d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -853,7 +853,7 @@
+ " " + reason + " " + pid + " " + token + " }";
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long pToken = proto.start(fieldId);
proto.write(ImportanceTokenProto.PID, pid);
if (token != null) {
@@ -1187,7 +1187,7 @@
tag = _tag;
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
@@ -1431,7 +1431,7 @@
}
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(UidObserverRegistrationProto.UID, uid);
proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
@@ -8365,6 +8365,31 @@
requestBugReportWithDescription(null, null, BugreportParams.BUGREPORT_MODE_REMOTE);
}
+ /**
+ * Launches a bugreport-whitelisted app to handle a bugreport.
+ *
+ * <p>Allows a bug report handler app to take bugreports on the user's behalf. The handler can
+ * be predefined in the config, meant to be launched with the primary user. The user can
+ * override this with a different (or same) handler app on possibly a different user. This is
+ * useful for capturing bug reports from work profile, for instance.
+ *
+ * @return true if there is a bugreport-whitelisted app to handle a bugreport, or false
+ * otherwise.
+ */
+ @Override
+ public boolean launchBugReportHandlerApp() {
+ if (!BugReportHandlerUtil.isBugReportHandlerEnabled(mContext)) {
+ return false;
+ }
+
+ // Always log caller, even if it does not have permission to dump.
+ Slog.i(TAG, "launchBugReportHandlerApp requested by UID " + Binder.getCallingUid());
+ enforceCallingPermission(android.Manifest.permission.DUMP,
+ "launchBugReportHandlerApp");
+
+ return BugReportHandlerUtil.launchBugReportHandlerApp(mContext);
+ }
+
public void registerProcessObserver(IProcessObserver observer) {
enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
"registerProcessObserver()");
@@ -10177,7 +10202,7 @@
}
} else if ("service".equals(cmd)) {
// output proto is ActivityManagerServiceDumpServicesProto
- mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
+ mServices.dumpDebug(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
} else if ("processes".equals(cmd) || "p".equals(cmd)) {
if (opti < args.length) {
dumpPackage = args[opti];
@@ -10199,7 +10224,7 @@
proto.end(broadcastToken);
long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
- mServices.writeToProto(proto,
+ mServices.dumpDebug(proto,
ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
proto.end(serviceToken);
@@ -11080,7 +11105,7 @@
if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
continue;
}
- r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS,
+ r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.PROCS,
mProcessList.mLruProcesses.indexOf(r)
);
if (r.isPersistent()) {
@@ -11094,7 +11119,7 @@
if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
continue;
}
- r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS,
+ r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS,
mProcessList.mLruProcesses.indexOf(r)
);
}
@@ -11105,7 +11130,7 @@
&& !ai.mTargetInfo.packageName.equals(dumpPackage)) {
continue;
}
- ai.writeToProto(proto,
+ ai.dumpDebug(proto,
ActivityManagerServiceDumpProcessesProto.ACTIVE_INSTRUMENTATIONS);
}
@@ -11115,7 +11140,7 @@
if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
continue;
}
- uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
+ uidRec.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
}
for (int i = 0; i < mValidateUids.size(); i++) {
@@ -11123,7 +11148,7 @@
if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
continue;
}
- uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
+ uidRec.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
}
if (mProcessList.getLruSizeLocked() > 0) {
@@ -11147,7 +11172,7 @@
if (!r.pkgList.containsKey(dumpPackage)) {
continue;
}
- r.writeToProto(proto,
+ r.dumpDebug(proto,
ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
}
}
@@ -11162,7 +11187,7 @@
|| !r.pkgList.containsKey(dumpPackage))) {
continue;
}
- it.writeToProto(proto,
+ it.dumpDebug(proto,
ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
}
}
@@ -11173,7 +11198,7 @@
if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
continue;
}
- r.writeToProto(proto,
+ r.dumpDebug(proto,
ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
}
@@ -11182,7 +11207,7 @@
if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
continue;
}
- r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
+ r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
}
for (int i=0; i<mProcessesOnHold.size(); i++) {
@@ -11190,17 +11215,17 @@
if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
continue;
}
- r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
+ r.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
}
writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS,
dumpPackage);
- mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS,
+ mAppErrors.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS,
dumpPackage);
mAtmInternal.writeProcessesToProto(proto, dumpPackage, mWakefulness, mTestPssMode);
if (dumpPackage == null) {
- mUserController.writeToProto(proto,
+ mUserController.dumpDebug(proto,
ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
}
@@ -11209,7 +11234,7 @@
final UidObserverRegistration reg = (UidObserverRegistration)
mUidObservers.getRegisteredCallbackCookie(i);
if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
- reg.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
+ reg.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
}
}
@@ -11223,7 +11248,7 @@
if (mPendingTempWhitelist.size() > 0) {
for (int i=0; i < mPendingTempWhitelist.size(); i++) {
- mPendingTempWhitelist.valueAt(i).writeToProto(proto,
+ mPendingTempWhitelist.valueAt(i).dumpDebug(proto,
ActivityManagerServiceDumpProcessesProto.PENDING_TEMP_WHITELIST);
}
}
@@ -11293,10 +11318,10 @@
final long token = proto.start(ActivityManagerServiceDumpProcessesProto.PROFILE);
proto.write(ActivityManagerServiceDumpProcessesProto.Profile.APP_NAME,
mProfileData.getProfileApp());
- mProfileData.getProfileProc().writeToProto(proto,
+ mProfileData.getProfileProc().dumpDebug(proto,
ActivityManagerServiceDumpProcessesProto.Profile.PROC);
if (mProfileData.getProfilerInfo() != null) {
- mProfileData.getProfilerInfo().writeToProto(proto,
+ mProfileData.getProfilerInfo().dumpDebug(proto,
ActivityManagerServiceDumpProcessesProto.Profile.INFO);
proto.write(ActivityManagerServiceDumpProcessesProto.Profile.TYPE,
mProfileType);
@@ -11339,7 +11364,7 @@
continue;
}
final long token = proto.start(fieldId);
- r.writeToProto(proto, ProcessToGcProto.PROC);
+ r.dumpDebug(proto, ProcessToGcProto.PROC);
proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
@@ -11578,12 +11603,12 @@
Iterator it = mRegisteredReceivers.values().iterator();
while (it.hasNext()) {
ReceiverList r = (ReceiverList)it.next();
- r.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_LIST);
+ r.dumpDebug(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_LIST);
}
}
- mReceiverResolver.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
+ mReceiverResolver.dumpDebug(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
for (BroadcastQueue q : mBroadcastQueues) {
- q.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
+ q.dumpDebug(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
}
for (int user=0; user<mStickyBroadcasts.size(); user++) {
long token = proto.start(ActivityManagerServiceDumpBroadcastsProto.STICKY_BROADCASTS);
@@ -11593,7 +11618,7 @@
long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
for (Intent intent : ent.getValue()) {
- intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
+ intent.dumpDebug(proto, StickyBroadcastProto.StickyAction.INTENTS,
false, true, true, false);
}
proto.end(actionToken);
@@ -11603,7 +11628,7 @@
long handlerToken = proto.start(ActivityManagerServiceDumpBroadcastsProto.HANDLER);
proto.write(ActivityManagerServiceDumpBroadcastsProto.MainHandler.HANDLER, mHandler.toString());
- mHandler.getLooper().writeToProto(proto,
+ mHandler.getLooper().dumpDebug(proto,
ActivityManagerServiceDumpBroadcastsProto.MainHandler.LOOPER);
proto.end(handlerToken);
}
@@ -11945,18 +11970,18 @@
proto.write(ProcessOomProto.STATE,
ProcessList.makeProcStateProtoEnum(r.getCurProcState()));
proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
- r.writeToProto(proto, ProcessOomProto.PROC);
+ r.dumpDebug(proto, ProcessOomProto.PROC);
proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
if (r.adjSource != null || r.adjTarget != null) {
if (r.adjTarget instanceof ComponentName) {
ComponentName cn = (ComponentName) r.adjTarget;
- cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
+ cn.dumpDebug(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
} else if (r.adjTarget != null) {
proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
}
if (r.adjSource instanceof ProcessRecord) {
ProcessRecord p = (ProcessRecord) r.adjSource;
- p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
+ p.dumpDebug(proto, ProcessOomProto.ADJ_SOURCE_PROC);
} else if (r.adjSource != null) {
proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
}
diff --git a/services/core/java/com/android/server/am/AppBindRecord.java b/services/core/java/com/android/server/am/AppBindRecord.java
index 9870420..28756a4 100644
--- a/services/core/java/com/android/server/am/AppBindRecord.java
+++ b/services/core/java/com/android/server/am/AppBindRecord.java
@@ -62,7 +62,7 @@
+ " " + service.shortInstanceName + ":" + client.processName + "}";
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(AppBindRecordProto.SERVICE_NAME, service.shortInstanceName);
proto.write(AppBindRecordProto.CLIENT_PROC_NAME, client.processName);
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 8095020..51e1718 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -106,7 +106,7 @@
mPackageWatchdog = watchdog;
}
- void writeToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId, String dumpPackage) {
if (mProcessCrashTimes.getMap().isEmpty() && mBadProcesses.getMap().isEmpty()) {
return;
}
diff --git a/services/core/java/com/android/server/am/AppTimeTracker.java b/services/core/java/com/android/server/am/AppTimeTracker.java
index debe0a9..2da6a33 100644
--- a/services/core/java/com/android/server/am/AppTimeTracker.java
+++ b/services/core/java/com/android/server/am/AppTimeTracker.java
@@ -122,7 +122,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId, boolean details) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, boolean details) {
final long token = proto.start(fieldId);
proto.write(AppTimeTrackerProto.RECEIVER, mReceiver.toString());
proto.write(AppTimeTrackerProto.TOTAL_DURATION_MS, mTotalTime);
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index 638111e..38030c2 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -15,22 +15,20 @@
*/
package com.android.server.am;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_LINK_LAYER_STATS;
-
import android.annotation.Nullable;
import android.bluetooth.BluetoothActivityEnergyInfo;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
-import android.net.wifi.IWifiManager;
-import android.net.wifi.WifiActivityEnergyInfo;
+import android.net.wifi.WifiManager;
import android.os.BatteryStats;
+import android.os.Bundle;
import android.os.Parcelable;
import android.os.Process;
-import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SynchronousResultReceiver;
import android.os.SystemClock;
import android.os.ThreadLocalWorkSource;
+import android.os.connectivity.WifiActivityEnergyInfo;
import android.telephony.ModemActivityInfo;
import android.telephony.TelephonyManager;
import android.util.IntArray;
@@ -45,6 +43,7 @@
import libcore.util.EmptyArray;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
@@ -117,7 +116,7 @@
private final Object mWorkerLock = new Object();
@GuardedBy("mWorkerLock")
- private IWifiManager mWifiManager = null;
+ private WifiManager mWifiManager = null;
@GuardedBy("mWorkerLock")
private TelephonyManager mTelephony = null;
@@ -411,21 +410,33 @@
if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI) != 0) {
// We were asked to fetch WiFi data.
- if (mWifiManager == null) {
- mWifiManager = IWifiManager.Stub.asInterface(ServiceManager.getService(
- Context.WIFI_SERVICE));
+ if (mWifiManager == null && ServiceManager.getService(Context.WIFI_SERVICE) != null) {
+ // this code is reached very early in the boot process, before Wifi Service has
+ // been registered. Check that ServiceManager.getService() returns a non null
+ // value before calling mContext.getSystemService(), since otherwise
+ // getSystemService() will throw a ServiceNotFoundException.
+ mWifiManager = mContext.getSystemService(WifiManager.class);
}
- if (mWifiManager != null) {
- try {
- // Only fetch WiFi power data if it is supported.
- if ((mWifiManager.getSupportedFeatures() & WIFI_FEATURE_LINK_LAYER_STATS) != 0) {
- wifiReceiver = new SynchronousResultReceiver("wifi");
- mWifiManager.requestActivityInfo(wifiReceiver);
- }
- } catch (RemoteException e) {
- // Oh well.
- }
+ // Only fetch WiFi power data if it is supported.
+ if (mWifiManager != null && mWifiManager.isEnhancedPowerReportingSupported()) {
+ SynchronousResultReceiver tempWifiReceiver = new SynchronousResultReceiver("wifi");
+ mWifiManager.getWifiActivityEnergyInfoAsync(
+ new Executor() {
+ @Override
+ public void execute(Runnable runnable) {
+ // run the listener on the binder thread, if it was run on the main
+ // thread it would deadlock since we would be waiting on ourselves
+ runnable.run();
+ }
+ },
+ info -> {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, info);
+ tempWifiReceiver.send(0, bundle);
+ }
+ );
+ wifiReceiver = tempWifiReceiver;
}
synchronized (mStats) {
mStats.updateRailStatsLocked();
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 8c60d0c..37026fd 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -23,7 +23,6 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.net.wifi.WifiActivityEnergyInfo;
import android.os.BatteryStats;
import android.os.BatteryStatsInternal;
import android.os.Binder;
@@ -43,6 +42,7 @@
import android.os.WorkSource;
import android.os.connectivity.CellularBatteryStats;
import android.os.connectivity.GpsBatteryStats;
+import android.os.connectivity.WifiActivityEnergyInfo;
import android.os.connectivity.WifiBatteryStats;
import android.os.health.HealthStatsParceler;
import android.os.health.HealthStatsWriter;
diff --git a/services/core/java/com/android/server/am/BroadcastDispatcher.java b/services/core/java/com/android/server/am/BroadcastDispatcher.java
index f8a3d1e..8afd52e 100644
--- a/services/core/java/com/android/server/am/BroadcastDispatcher.java
+++ b/services/core/java/com/android/server/am/BroadcastDispatcher.java
@@ -73,9 +73,9 @@
return broadcasts.isEmpty();
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
for (BroadcastRecord br : broadcasts) {
- br.writeToProto(proto, fieldId);
+ br.dumpDebug(proto, fieldId);
}
}
@@ -415,18 +415,18 @@
/**
* Standard proto dump entry point
*/
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
if (mCurrentBroadcast != null) {
- mCurrentBroadcast.writeToProto(proto, fieldId);
+ mCurrentBroadcast.dumpDebug(proto, fieldId);
}
for (Deferrals d : mAlarmBroadcasts) {
- d.writeToProto(proto, fieldId);
+ d.dumpDebug(proto, fieldId);
}
for (BroadcastRecord br : mOrderedBroadcasts) {
- br.writeToProto(proto, fieldId);
+ br.dumpDebug(proto, fieldId);
}
for (Deferrals d : mDeferredBroadcasts) {
- d.writeToProto(proto, fieldId);
+ d.dumpDebug(proto, fieldId);
}
}
diff --git a/services/core/java/com/android/server/am/BroadcastFilter.java b/services/core/java/com/android/server/am/BroadcastFilter.java
index 34fca23..1ec8db0 100644
--- a/services/core/java/com/android/server/am/BroadcastFilter.java
+++ b/services/core/java/com/android/server/am/BroadcastFilter.java
@@ -46,9 +46,9 @@
visibleToInstantApp = _visibleToInstantApp;
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
- super.writeToProto(proto, BroadcastFilterProto.INTENT_FILTER);
+ super.dumpDebug(proto, BroadcastFilterProto.INTENT_FILTER);
if (requiredPermission != null) {
proto.write(BroadcastFilterProto.REQUIRED_PERMISSION, requiredPermission);
}
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 1d03b36..10492a7 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1915,17 +1915,17 @@
}
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(BroadcastQueueProto.QUEUE_NAME, mQueueName);
int N;
N = mParallelBroadcasts.size();
for (int i = N - 1; i >= 0; i--) {
- mParallelBroadcasts.get(i).writeToProto(proto, BroadcastQueueProto.PARALLEL_BROADCASTS);
+ mParallelBroadcasts.get(i).dumpDebug(proto, BroadcastQueueProto.PARALLEL_BROADCASTS);
}
- mDispatcher.writeToProto(proto, BroadcastQueueProto.ORDERED_BROADCASTS);
+ mDispatcher.dumpDebug(proto, BroadcastQueueProto.ORDERED_BROADCASTS);
if (mPendingBroadcast != null) {
- mPendingBroadcast.writeToProto(proto, BroadcastQueueProto.PENDING_BROADCAST);
+ mPendingBroadcast.dumpDebug(proto, BroadcastQueueProto.PENDING_BROADCAST);
}
int lastIndex = mHistoryNext;
@@ -1936,7 +1936,7 @@
ringIndex = ringAdvance(ringIndex, -1, MAX_BROADCAST_HISTORY);
BroadcastRecord r = mBroadcastHistory[ringIndex];
if (r != null) {
- r.writeToProto(proto, BroadcastQueueProto.HISTORICAL_BROADCASTS);
+ r.dumpDebug(proto, BroadcastQueueProto.HISTORICAL_BROADCASTS);
}
} while (ringIndex != lastIndex);
@@ -1948,7 +1948,7 @@
continue;
}
long summaryToken = proto.start(BroadcastQueueProto.HISTORICAL_BROADCASTS_SUMMARY);
- intent.writeToProto(proto, BroadcastQueueProto.BroadcastSummary.INTENT,
+ intent.dumpDebug(proto, BroadcastQueueProto.BroadcastSummary.INTENT,
false, true, true, false);
proto.write(BroadcastQueueProto.BroadcastSummary.ENQUEUE_CLOCK_TIME_MS,
mSummaryHistoryEnqueueTime[ringIndex]);
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 1352504..f263886 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -417,7 +417,7 @@
+ " u" + userId + " " + intent.getAction() + "}";
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(BroadcastRecordProto.USER_ID, userId);
proto.write(BroadcastRecordProto.INTENT_ACTION, intent.getAction());
diff --git a/services/core/java/com/android/server/am/BugReportHandlerUtil.java b/services/core/java/com/android/server/am/BugReportHandlerUtil.java
new file mode 100644
index 0000000..ba89fce
--- /dev/null
+++ b/services/core/java/com/android/server/am/BugReportHandlerUtil.java
@@ -0,0 +1,179 @@
+/*
+ * 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.server.am;
+
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.app.BroadcastOptions;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Binder;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.Slog;
+
+import com.android.server.SystemConfig;
+
+import java.util.List;
+
+/**
+ * Static utility methods related to BugReportHandler.
+ */
+public final class BugReportHandlerUtil {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "BugReportHandlerUtil" : TAG_AM;
+ private static final String SHELL_APP_PACKAGE = "com.android.shell";
+ private static final String INTENT_BUGREPORT_REQUESTED =
+ "com.android.internal.intent.action.BUGREPORT_REQUESTED";
+
+ /**
+ * Check is BugReportHandler enabled on the device.
+ *
+ * @param context Context
+ * @return true if BugReportHandler is enabled, or false otherwise
+ */
+ static boolean isBugReportHandlerEnabled(Context context) {
+ return context.getResources().getBoolean(
+ com.android.internal.R.bool.config_bugReportHandlerEnabled);
+ }
+
+ /**
+ * Launches a bugreport-whitelisted app to handle a bugreport.
+ *
+ * <p>Allows a bug report handler app to take bugreports on the user's behalf. The handler can
+ * be predefined in the config, meant to be launched with the primary user. The user can
+ * override this with a different (or same) handler app on possibly a different user. This is
+ * useful for capturing bug reports from work profile, for instance.
+ *
+ * @param context Context
+ * @return true if there is a bugreport-whitelisted app to handle a bugreport, or false
+ * otherwise
+ */
+ static boolean launchBugReportHandlerApp(Context context) {
+ if (!isBugReportHandlerEnabled(context)) {
+ return false;
+ }
+
+ String handlerApp = getCustomBugReportHandlerApp(context);
+ if (isShellApp(handlerApp)) {
+ return false;
+ }
+
+ int handlerUser = getCustomBugReportHandlerUser(context);
+ if (!isValidBugReportHandlerApp(handlerApp)) {
+ handlerApp = getDefaultBugReportHandlerApp(context);
+ handlerUser = UserHandle.USER_SYSTEM;
+ } else if (getBugReportHandlerAppReceivers(context, handlerApp, handlerUser).isEmpty()) {
+ // It looks like the settings are outdated, reset outdated settings.
+ //
+ // i.e.
+ // If user chooses which profile and which bugreport-whitelisted app in that
+ // profile to handle a bugreport, then user remove the profile.
+ // === RESULT ===
+ // The chosen bugreport handler app is outdated because the profile is removed,
+ // so reset the chosen app and profile
+ handlerApp = getDefaultBugReportHandlerApp(context);
+ handlerUser = UserHandle.USER_SYSTEM;
+ resetCustomBugreportHandlerAppAndUser(context);
+ }
+
+ if (isShellApp(handlerApp) || !isValidBugReportHandlerApp(handlerApp)
+ || getBugReportHandlerAppReceivers(context, handlerApp, handlerUser).isEmpty()) {
+ return false;
+ }
+
+ Slog.i(TAG, "Launching bug report handler app: " + handlerApp);
+ Intent intent = new Intent(INTENT_BUGREPORT_REQUESTED);
+ intent.setPackage(handlerApp);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ // Send broadcast to the receiver while allowing starting activity from background
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setBackgroundActivityStartsAllowed(true);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ context.sendBroadcastAsUser(intent, UserHandle.of(handlerUser),
+ android.Manifest.permission.DUMP,
+ options.toBundle());
+ } catch (RuntimeException e) {
+ Slog.e(TAG, "Error while trying to launch bugreport handler app.", e);
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ return true;
+ }
+
+ private static String getCustomBugReportHandlerApp(Context context) {
+ // Get the package of custom bugreport handler app
+ return Settings.Global.getString(context.getContentResolver(),
+ Settings.Global.CUSTOM_BUGREPORT_HANDLER_APP);
+ }
+
+ private static int getCustomBugReportHandlerUser(Context context) {
+ return Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.CUSTOM_BUGREPORT_HANDLER_USER, UserHandle.USER_NULL);
+ }
+
+ private static boolean isShellApp(String app) {
+ return SHELL_APP_PACKAGE.equals(app);
+ }
+
+ private static boolean isValidBugReportHandlerApp(String app) {
+ return !TextUtils.isEmpty(app) && isBugreportWhitelistedApp(app);
+ }
+
+ private static boolean isBugreportWhitelistedApp(String app) {
+ // Verify the app is bugreport-whitelisted
+ final ArraySet<String> whitelistedApps = SystemConfig.getInstance()
+ .getBugreportWhitelistedPackages();
+ return whitelistedApps.contains(app);
+ }
+
+ private static List<ResolveInfo> getBugReportHandlerAppReceivers(Context context,
+ String handlerApp, int handlerUser) {
+ // Use the app package and the user id to retrieve the receiver that can handle a
+ // broadcast of the intent.
+ Intent intent = new Intent(INTENT_BUGREPORT_REQUESTED);
+ intent.setPackage(handlerApp);
+ return context.getPackageManager()
+ .queryBroadcastReceiversAsUser(intent, PackageManager.MATCH_SYSTEM_ONLY,
+ handlerUser);
+ }
+
+ private static String getDefaultBugReportHandlerApp(Context context) {
+ return context.getResources().getString(
+ com.android.internal.R.string.config_defaultBugReportHandlerApp);
+ }
+
+ private static void resetCustomBugreportHandlerAppAndUser(Context context) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ Settings.Global.putString(context.getContentResolver(),
+ Settings.Global.CUSTOM_BUGREPORT_HANDLER_APP,
+ getDefaultBugReportHandlerApp(context));
+ Settings.Global.putInt(context.getContentResolver(),
+ Settings.Global.CUSTOM_BUGREPORT_HANDLER_USER, UserHandle.USER_SYSTEM);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java
index 4595084..6d9d3fb 100644
--- a/services/core/java/com/android/server/am/ConnectionRecord.java
+++ b/services/core/java/com/android/server/am/ConnectionRecord.java
@@ -232,7 +232,7 @@
return stringName = sb.toString();
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
if (binding == null) return; // if binding is null, don't write data, something is wrong.
long token = proto.start(fieldId);
proto.write(ConnectionRecordProto.HEX_HASH,
diff --git a/services/core/java/com/android/server/am/IntentBindRecord.java b/services/core/java/com/android/server/am/IntentBindRecord.java
index 90aef3e..e622013 100644
--- a/services/core/java/com/android/server/am/IntentBindRecord.java
+++ b/services/core/java/com/android/server/am/IntentBindRecord.java
@@ -108,10 +108,10 @@
return stringName = sb.toString();
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
if (intent != null) {
- intent.getIntent().writeToProto(proto,
+ intent.getIntent().dumpDebug(proto,
IntentBindRecordProto.INTENT, false, true, false, false);
}
if (binder != null) {
@@ -128,7 +128,7 @@
for (int i=0; i<N; i++) {
AppBindRecord a = apps.valueAt(i);
if (a != null) {
- a.writeToProto(proto, IntentBindRecordProto.APPS);
+ a.dumpDebug(proto, IntentBindRecordProto.APPS);
}
}
proto.end(token);
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 0591704..12f4656 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -376,7 +376,11 @@
ConnectionRecord cr = pr.connections.valueAt(i);
ProcessRecord service = (cr.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0
? cr.binding.service.isolatedProc : cr.binding.service.app;
- if (service == null || service == pr || (containsCycle |= service.mReachable)) {
+ if (service == null || service == pr) {
+ continue;
+ }
+ containsCycle |= service.mReachable;
+ if (service.mReachable) {
continue;
}
if ((cr.flags & (Context.BIND_WAIVE_PRIORITY
@@ -394,6 +398,10 @@
if (provider == null || provider == pr || (containsCycle |= provider.mReachable)) {
continue;
}
+ containsCycle |= provider.mReachable;
+ if (provider.mReachable) {
+ continue;
+ }
queue.offer(provider);
provider.mReachable = true;
}
@@ -482,12 +490,15 @@
// need to reset cycle state before calling computeOomAdjLocked because of service conns
for (int i = numProc - 1; i >= 0; i--) {
ProcessRecord app = activeProcesses.get(i);
- app.containsCycle = false;
app.mReachable = false;
- app.setCurRawProcState(PROCESS_STATE_CACHED_EMPTY);
- app.setCurRawAdj(ProcessList.UNKNOWN_ADJ);
- app.setCapability = PROCESS_CAPABILITY_NONE;
- app.resetCachedInfo();
+ // No need to compute again it has been evaluated in previous iteration
+ if (app.adjSeq != mAdjSeq) {
+ app.containsCycle = false;
+ app.setCurRawProcState(PROCESS_STATE_CACHED_EMPTY);
+ app.setCurRawAdj(ProcessList.UNKNOWN_ADJ);
+ app.setCapability = PROCESS_CAPABILITY_NONE;
+ app.resetCachedInfo();
+ }
}
for (int i = numProc - 1; i >= 0; i--) {
ProcessRecord app = activeProcesses.get(i);
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 5db6ff7..6f6f193 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -804,11 +804,11 @@
}
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
- writeToProto(proto, fieldId, -1);
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
+ dumpDebug(proto, fieldId, -1);
}
- public void writeToProto(ProtoOutputStream proto, long fieldId, int lruIndex) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, int lruIndex) {
long token = proto.start(fieldId);
proto.write(ProcessRecordProto.PID, pid);
proto.write(ProcessRecordProto.PROCESS_NAME, processName);
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index 5c840ad..3ada0c3 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -611,7 +611,7 @@
try {
FileOutputStream fout = new ParcelFileDescriptor.AutoCloseOutputStream(fds[1]);
final ProtoOutputStream proto = new ProtoOutputStream(fout);
- stats.writeToProto(proto, stats.mTimePeriodEndRealtime, section);
+ stats.dumpDebug(proto, stats.mTimePeriodEndRealtime, section);
proto.flush();
fout.close();
} catch (IOException e) {
@@ -1213,7 +1213,7 @@
return;
}
final long token = proto.start(fieldId);
- stats.writeToProto(proto, now, ProcessStats.REPORT_ALL);
+ stats.dumpDebug(proto, now, ProcessStats.REPORT_ALL);
proto.end(token);
}
@@ -1225,7 +1225,7 @@
synchronized (mAm) {
now = SystemClock.uptimeMillis();
final long token = proto.start(ProcessStatsServiceDumpProto.PROCSTATS_NOW);
- mProcessStats.writeToProto(proto, now, ProcessStats.REPORT_ALL);
+ mProcessStats.dumpDebug(proto, now, ProcessStats.REPORT_ALL);
proto.end(token);
}
diff --git a/services/core/java/com/android/server/am/ReceiverList.java b/services/core/java/com/android/server/am/ReceiverList.java
index 5e31b2e..ff34fd3 100644
--- a/services/core/java/com/android/server/am/ReceiverList.java
+++ b/services/core/java/com/android/server/am/ReceiverList.java
@@ -80,20 +80,20 @@
return false;
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
- app.writeToProto(proto, ReceiverListProto.APP);
+ app.dumpDebug(proto, ReceiverListProto.APP);
proto.write(ReceiverListProto.PID, pid);
proto.write(ReceiverListProto.UID, uid);
proto.write(ReceiverListProto.USER, userId);
if (curBroadcast != null) {
- curBroadcast.writeToProto(proto, ReceiverListProto.CURRENT);
+ curBroadcast.dumpDebug(proto, ReceiverListProto.CURRENT);
}
proto.write(ReceiverListProto.LINKED_TO_DEATH, linkedToDeath);
final int N = size();
for (int i=0; i<N; i++) {
BroadcastFilter bf = get(i);
- bf.writeToProto(proto, ReceiverListProto.FILTERS);
+ bf.dumpDebug(proto, ReceiverListProto.FILTERS);
}
proto.write(ReceiverListProto.HEX_HASH, Integer.toHexString(System.identityHashCode(this)));
proto.end(token);
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 5106b0e..ad316d5 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -177,7 +177,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId, long now) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, long now) {
long token = proto.start(fieldId);
proto.write(ServiceRecordProto.StartItem.ID, id);
ProtoUtils.toDuration(proto,
@@ -185,14 +185,14 @@
proto.write(ServiceRecordProto.StartItem.DELIVERY_COUNT, deliveryCount);
proto.write(ServiceRecordProto.StartItem.DONE_EXECUTING_COUNT, doneExecutingCount);
if (intent != null) {
- intent.writeToProto(proto, ServiceRecordProto.StartItem.INTENT, true, true,
+ intent.dumpDebug(proto, ServiceRecordProto.StartItem.INTENT, true, true,
true, false);
}
if (neededGrants != null) {
- neededGrants.writeToProto(proto, ServiceRecordProto.StartItem.NEEDED_GRANTS);
+ neededGrants.dumpDebug(proto, ServiceRecordProto.StartItem.NEEDED_GRANTS);
}
if (uriPermissions != null) {
- uriPermissions.writeToProto(proto, ServiceRecordProto.StartItem.URI_PERMISSIONS);
+ uriPermissions.dumpDebug(proto, ServiceRecordProto.StartItem.URI_PERMISSIONS);
}
proto.end(token);
}
@@ -247,7 +247,7 @@
}
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(ServiceRecordProto.SHORT_NAME, this.shortInstanceName);
proto.write(ServiceRecordProto.IS_RUNNING, app != null);
@@ -255,7 +255,7 @@
proto.write(ServiceRecordProto.PID, app.pid);
}
if (intent != null) {
- intent.getIntent().writeToProto(proto, ServiceRecordProto.INTENT, false, true, false,
+ intent.getIntent().dumpDebug(proto, ServiceRecordProto.INTENT, false, true, false,
false);
}
proto.write(ServiceRecordProto.PACKAGE_NAME, packageName);
@@ -274,17 +274,17 @@
proto.end(appInfoToken);
}
if (app != null) {
- app.writeToProto(proto, ServiceRecordProto.APP);
+ app.dumpDebug(proto, ServiceRecordProto.APP);
}
if (isolatedProc != null) {
- isolatedProc.writeToProto(proto, ServiceRecordProto.ISOLATED_PROC);
+ isolatedProc.dumpDebug(proto, ServiceRecordProto.ISOLATED_PROC);
}
proto.write(ServiceRecordProto.WHITELIST_MANAGER, whitelistManager);
proto.write(ServiceRecordProto.DELAYED, delayed);
if (isForeground || foregroundId != 0) {
long fgToken = proto.start(ServiceRecordProto.FOREGROUND);
proto.write(ServiceRecordProto.Foreground.ID, foregroundId);
- foregroundNoti.writeToProto(proto, ServiceRecordProto.Foreground.NOTIFICATION);
+ foregroundNoti.dumpDebug(proto, ServiceRecordProto.Foreground.NOTIFICATION);
proto.end(fgToken);
}
ProtoUtils.toDuration(proto, ServiceRecordProto.CREATE_REAL_TIME, createRealTime, nowReal);
@@ -327,21 +327,21 @@
if (deliveredStarts.size() > 0) {
final int N = deliveredStarts.size();
for (int i = 0; i < N; i++) {
- deliveredStarts.get(i).writeToProto(proto,
+ deliveredStarts.get(i).dumpDebug(proto,
ServiceRecordProto.DELIVERED_STARTS, now);
}
}
if (pendingStarts.size() > 0) {
final int N = pendingStarts.size();
for (int i = 0; i < N; i++) {
- pendingStarts.get(i).writeToProto(proto, ServiceRecordProto.PENDING_STARTS, now);
+ pendingStarts.get(i).dumpDebug(proto, ServiceRecordProto.PENDING_STARTS, now);
}
}
if (bindings.size() > 0) {
final int N = bindings.size();
for (int i=0; i<N; i++) {
IntentBindRecord b = bindings.valueAt(i);
- b.writeToProto(proto, ServiceRecordProto.BINDINGS);
+ b.dumpDebug(proto, ServiceRecordProto.BINDINGS);
}
}
if (connections.size() > 0) {
@@ -349,7 +349,7 @@
for (int conni=0; conni<N; conni++) {
ArrayList<ConnectionRecord> c = connections.valueAt(conni);
for (int i=0; i<c.size(); i++) {
- c.get(i).writeToProto(proto, ServiceRecordProto.CONNECTIONS);
+ c.get(i).dumpDebug(proto, ServiceRecordProto.CONNECTIONS);
}
}
}
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index e6cf287..acf8b2e 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -156,7 +156,7 @@
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(UidRecordProto.UID, uid);
proto.write(UidRecordProto.CURRENT, ProcessList.makeProcStateProtoEnum(mCurProcState));
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 53ac4ec..728291d 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -2100,14 +2100,14 @@
}
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
synchronized (mLock) {
long token = proto.start(fieldId);
for (int i = 0; i < mStartedUsers.size(); i++) {
UserState uss = mStartedUsers.valueAt(i);
final long uToken = proto.start(UserControllerProto.STARTED_USERS);
proto.write(UserControllerProto.User.ID, uss.mHandle.getIdentifier());
- uss.writeToProto(proto, UserControllerProto.User.STATE);
+ uss.dumpDebug(proto, UserControllerProto.User.STATE);
proto.end(uToken);
}
for (int i = 0; i < mStartedUserArray.length; i++) {
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index f51b3c6..1fe7608 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -139,7 +139,7 @@
pw.println();
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(UserStateProto.STATE, stateToProtoEnum(state));
proto.write(UserStateProto.SWITCHING, switching);
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index 95582f7..2eec419 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -55,7 +55,7 @@
private Map<String, Boolean> mPackageOverrides;
public CompatChange(long changeId) {
- this(changeId, null, -1, false);
+ this(changeId, null, -1, false, null);
}
/**
@@ -66,8 +66,8 @@
* @param disabled If {@code true}, overrides any {@code enableAfterTargetSdk} set.
*/
public CompatChange(long changeId, @Nullable String name, int enableAfterTargetSdk,
- boolean disabled) {
- super(changeId, name, enableAfterTargetSdk, disabled);
+ boolean disabled, String description) {
+ super(changeId, name, enableAfterTargetSdk, disabled, description);
}
/**
@@ -75,7 +75,7 @@
*/
public CompatChange(Change change) {
super(change.getId(), change.getName(), change.getEnableAfterTargetSdk(),
- change.getDisabled());
+ change.getDisabled(), change.getDescription());
}
void registerListener(ChangeListener listener) {
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 39c6e75..cf83dd6 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -319,7 +319,8 @@
changeInfos[i] = new CompatibilityChangeInfo(change.getId(),
change.getName(),
change.getEnableAfterTargetSdk(),
- change.getDisabled());
+ change.getDisabled(),
+ change.getDescription());
}
return changeInfos;
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index bc83780..2179518 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -31,7 +31,6 @@
import android.net.StringNetworkSpecifier;
import android.net.wifi.WifiInfo;
import android.os.UserHandle;
-import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -105,8 +104,7 @@
return -1;
}
- // TODO: Remove @TransportType or change it to @Transport.
- private static String getTransportName(@TransportType int transportType) {
+ private static String getTransportName(final int transportType) {
Resources r = Resources.getSystem();
String[] networkTypes = r.getStringArray(R.array.network_switch_type_name);
try {
diff --git a/services/core/java/com/android/server/integrity/model/BitInputStream.java b/services/core/java/com/android/server/integrity/model/BitInputStream.java
new file mode 100644
index 0000000..09bc7e8
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/model/BitInputStream.java
@@ -0,0 +1,66 @@
+/*
+ * 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.server.integrity.model;
+
+/** A wrapper class for reading a stream of bits. */
+public class BitInputStream {
+
+ private byte[] mRuleBytes;
+ private long mBitPointer;
+
+ public BitInputStream(byte[] ruleBytes) {
+ this.mRuleBytes = ruleBytes;
+ this.mBitPointer = 0;
+ }
+
+ /**
+ * Read the next number of bits from the stream.
+ *
+ * @param numOfBits The number of bits to read.
+ * @return The value read from the stream.
+ */
+ public int getNext(int numOfBits) {
+ int component = 0;
+ int count = 0;
+
+ int idx = (int) (mBitPointer / 8);
+ int offset = 7 - (int) (mBitPointer % 8);
+
+ while (count++ < numOfBits) {
+ if (idx >= mRuleBytes.length) {
+ throw new IllegalArgumentException(String.format("Invalid byte index: %d", idx));
+ }
+
+ component <<= 1;
+ component |= (mRuleBytes[idx] >>> offset) & 1;
+
+ offset--;
+ if (offset == -1) {
+ idx++;
+ offset = 7;
+ }
+ }
+
+ mBitPointer += numOfBits;
+ return component;
+ }
+
+ /** Check if there are bits left in the stream. */
+ public boolean hasNext() {
+ return mBitPointer / 8 < mRuleBytes.length;
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/model/BitOutputStream.java b/services/core/java/com/android/server/integrity/model/BitOutputStream.java
new file mode 100644
index 0000000..ecb9189
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/model/BitOutputStream.java
@@ -0,0 +1,86 @@
+/*
+ * 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.server.integrity.model;
+
+import java.util.BitSet;
+
+/** A wrapper class for writing a stream of bits. */
+public class BitOutputStream {
+
+ private BitSet mBitSet;
+ private int mIndex;
+
+ public BitOutputStream() {
+ mBitSet = new BitSet();
+ mIndex = 0;
+ }
+
+ /**
+ * Set the next number of bits in the stream to value.
+ *
+ * @param numOfBits The number of bits used to represent the value.
+ * @param value The value to convert to bits.
+ */
+ public void setNext(int numOfBits, int value) {
+ if (numOfBits <= 0) {
+ return;
+ }
+ int offset = 1 << (numOfBits - 1);
+ while (numOfBits-- > 0) {
+ mBitSet.set(mIndex, (value & offset) != 0);
+ offset >>= 1;
+ mIndex++;
+ }
+ }
+
+ /**
+ * Set the next bit in the stream to value.
+ *
+ * @param value The value to set the bit to.
+ */
+ public void setNext(boolean value) {
+ mBitSet.set(mIndex, value);
+ mIndex++;
+ }
+
+ /** Set the next bit in the stream to true. */
+ public void setNext() {
+ setNext(/* value= */ true);
+ }
+
+ /** Convert BitSet in big-endian to ByteArray in big-endian. */
+ public byte[] toByteArray() {
+ int bitSetSize = mBitSet.length();
+ int numOfBytes = bitSetSize / 8;
+ if (bitSetSize % 8 != 0) {
+ numOfBytes++;
+ }
+ byte[] bytes = new byte[numOfBytes];
+ for (int i = 0; i < mBitSet.length(); i++) {
+ if (mBitSet.get(i)) {
+ bytes[i / 8] |= 1 << (7 - (i % 8));
+ }
+ }
+ return bytes;
+ }
+
+ /** Clear the stream. */
+ public void clear() {
+ mBitSet.clear();
+ mIndex = 0;
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/model/ComponentBitSize.java b/services/core/java/com/android/server/integrity/model/ComponentBitSize.java
new file mode 100644
index 0000000..d47ce2d
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/model/ComponentBitSize.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.integrity.model;
+
+import android.content.integrity.Rule;
+
+/**
+ * A helper class containing information about the binary representation of different {@link Rule}
+ * components.
+ */
+public final class ComponentBitSize {
+ public static final int FORMAT_VERSION_BITS = 5;
+ public static final int EFFECT_BITS = 3;
+ public static final int KEY_BITS = 4;
+ public static final int OPERATOR_BITS = 3;
+ public static final int CONNECTOR_BITS = 2;
+ public static final int SEPARATOR_BITS = 2;
+ public static final int VALUE_SIZE_BITS = 5;
+ public static final int IS_HASHED_BITS = 1;
+
+ public static final int ATOMIC_FORMULA_START = 0;
+ public static final int COMPOUND_FORMULA_START = 1;
+ public static final int COMPOUND_FORMULA_END = 2;
+
+ public static final int DEFAULT_FORMAT_VERSION = 1;
+ public static final int SIGNAL_BIT = 1;
+}
diff --git a/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java b/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java
index aad177e..8aa0751 100644
--- a/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java
+++ b/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java
@@ -16,23 +16,132 @@
package com.android.server.integrity.parser;
+import static com.android.server.integrity.model.ComponentBitSize.ATOMIC_FORMULA_START;
+import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_END;
+import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_START;
+import static com.android.server.integrity.model.ComponentBitSize.CONNECTOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.EFFECT_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.FORMAT_VERSION_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.IS_HASHED_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.KEY_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.SIGNAL_BIT;
+import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS;
+
+import android.content.integrity.AtomicFormula;
+import android.content.integrity.CompoundFormula;
+import android.content.integrity.Formula;
import android.content.integrity.Rule;
+import com.android.server.integrity.model.BitInputStream;
+
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.List;
/** A helper class to parse rules into the {@link Rule} model from Binary representation. */
public class RuleBinaryParser implements RuleParser {
@Override
- public List<Rule> parse(byte[] ruleBytes) {
- // TODO: Implement binary text parser.
- return null;
+ public List<Rule> parse(byte[] ruleBytes) throws RuleParseException {
+ try {
+ BitInputStream bitInputStream = new BitInputStream(ruleBytes);
+ return parseRules(bitInputStream);
+ } catch (Exception e) {
+ throw new RuleParseException(e.getMessage(), e);
+ }
}
@Override
- public List<Rule> parse(InputStream inputStream) {
- // TODO: Implement stream parser.
- return null;
+ public List<Rule> parse(InputStream inputStream) throws RuleParseException {
+ try {
+ byte[] ruleBytes = new byte[inputStream.available()];
+ inputStream.read(ruleBytes);
+ return parse(ruleBytes);
+ } catch (Exception e) {
+ throw new RuleParseException(e.getMessage(), e);
+ }
+ }
+
+ private List<Rule> parseRules(BitInputStream bitInputStream) {
+ List<Rule> parsedRules = new ArrayList<>();
+
+ // Read the rule binary file format version.
+ bitInputStream.getNext(FORMAT_VERSION_BITS);
+
+ while (bitInputStream.hasNext()) {
+ if (bitInputStream.getNext(SIGNAL_BIT) == 1) {
+ parsedRules.add(parseRule(bitInputStream));
+ }
+ }
+
+ return parsedRules;
+ }
+
+ private Rule parseRule(BitInputStream bitInputStream) {
+ Formula formula = parseFormula(bitInputStream);
+ int effect = bitInputStream.getNext(EFFECT_BITS);
+
+ if (bitInputStream.getNext(SIGNAL_BIT) != 1) {
+ throw new IllegalArgumentException("A rule must end with a '1' bit.");
+ }
+
+ return new Rule(formula, effect);
+ }
+
+ private Formula parseFormula(BitInputStream bitInputStream) {
+ int separator = bitInputStream.getNext(SEPARATOR_BITS);
+ switch (separator) {
+ case ATOMIC_FORMULA_START:
+ return parseAtomicFormula(bitInputStream);
+ case COMPOUND_FORMULA_START:
+ return parseCompoundFormula(bitInputStream);
+ case COMPOUND_FORMULA_END:
+ return null;
+ default:
+ throw new IllegalArgumentException(
+ String.format("Unknown formula separator: %s", separator));
+ }
+ }
+
+ private CompoundFormula parseCompoundFormula(BitInputStream bitInputStream) {
+ int connector = bitInputStream.getNext(CONNECTOR_BITS);
+ List<Formula> formulas = new ArrayList<>();
+
+ Formula parsedFormula = parseFormula(bitInputStream);
+ while (parsedFormula != null) {
+ formulas.add(parsedFormula);
+ parsedFormula = parseFormula(bitInputStream);
+ }
+
+ return new CompoundFormula(connector, formulas);
+ }
+
+ private AtomicFormula parseAtomicFormula(BitInputStream bitInputStream) {
+ int key = bitInputStream.getNext(KEY_BITS);
+ int operator = bitInputStream.getNext(OPERATOR_BITS);
+
+ boolean isHashedValue = bitInputStream.getNext(IS_HASHED_BITS) == 1;
+ int valueSize = bitInputStream.getNext(VALUE_SIZE_BITS);
+ StringBuilder value = new StringBuilder();
+ while (valueSize-- > 0) {
+ value.append((char) bitInputStream.getNext(/* numOfBits= */ 8));
+ }
+
+ switch (key) {
+ case AtomicFormula.PACKAGE_NAME:
+ case AtomicFormula.APP_CERTIFICATE:
+ case AtomicFormula.INSTALLER_NAME:
+ case AtomicFormula.INSTALLER_CERTIFICATE:
+ return new AtomicFormula.StringAtomicFormula(key, value.toString(), isHashedValue);
+ case AtomicFormula.VERSION_CODE:
+ return new AtomicFormula.IntAtomicFormula(
+ key, operator, Integer.parseInt(value.toString()));
+ case AtomicFormula.PRE_INSTALLED:
+ return new AtomicFormula.BooleanAtomicFormula(key, value.toString().equals("1"));
+ default:
+ throw new IllegalArgumentException(String.format("Unknown key: %d", key));
+ }
}
}
diff --git a/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java b/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java
index 2e99d0f..d405583 100644
--- a/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java
+++ b/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java
@@ -41,7 +41,7 @@
private static final String NAMESPACE = "";
private static final String RULE_LIST_TAG = "RL";
private static final String RULE_TAG = "R";
- private static final String OPEN_FORMULA_TAG = "OF";
+ private static final String COMPOUND_FORMULA_TAG = "OF";
private static final String ATOMIC_FORMULA_TAG = "AF";
private static final String EFFECT_ATTRIBUTE = "E";
private static final String KEY_ATTRIBUTE = "K";
@@ -118,8 +118,8 @@
if (eventType == XmlPullParser.START_TAG) {
switch (nodeName) {
- case OPEN_FORMULA_TAG:
- formula = parseOpenFormula(parser);
+ case COMPOUND_FORMULA_TAG:
+ formula = parseCompoundFormula(parser);
break;
case ATOMIC_FORMULA_TAG:
formula = parseAtomicFormula(parser);
@@ -137,7 +137,7 @@
return new Rule(formula, effect);
}
- private static Formula parseOpenFormula(XmlPullParser parser)
+ private static Formula parseCompoundFormula(XmlPullParser parser)
throws IOException, XmlPullParserException {
int connector =
Integer.parseInt(extractAttributeValue(parser, CONNECTOR_ATTRIBUTE).orElse("-1"));
@@ -147,7 +147,8 @@
while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) {
String nodeName = parser.getName();
- if (eventType == XmlPullParser.END_TAG && parser.getName().equals(OPEN_FORMULA_TAG)) {
+ if (eventType == XmlPullParser.END_TAG
+ && parser.getName().equals(COMPOUND_FORMULA_TAG)) {
break;
}
@@ -156,8 +157,8 @@
case ATOMIC_FORMULA_TAG:
formulas.add(parseAtomicFormula(parser));
break;
- case OPEN_FORMULA_TAG:
- formulas.add(parseOpenFormula(parser));
+ case COMPOUND_FORMULA_TAG:
+ formulas.add(parseCompoundFormula(parser));
break;
default:
throw new RuntimeException(
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
index d4f41eb..b988fd4 100644
--- a/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
+++ b/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
@@ -16,24 +16,155 @@
package com.android.server.integrity.serializer;
+import static com.android.server.integrity.model.ComponentBitSize.ATOMIC_FORMULA_START;
+import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_END;
+import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_START;
+import static com.android.server.integrity.model.ComponentBitSize.CONNECTOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.DEFAULT_FORMAT_VERSION;
+import static com.android.server.integrity.model.ComponentBitSize.EFFECT_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.FORMAT_VERSION_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.KEY_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS;
+
+import android.content.integrity.AtomicFormula;
+import android.content.integrity.CompoundFormula;
+import android.content.integrity.Formula;
import android.content.integrity.Rule;
+import com.android.server.integrity.model.BitOutputStream;
+
+import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Optional;
-/** A helper class to serialize rules from the {@link Rule} model to Xml representation. */
+/** A helper class to serialize rules from the {@link Rule} model to Binary representation. */
public class RuleBinarySerializer implements RuleSerializer {
+ // Get the byte representation for a list of rules, and write them to an output stream.
@Override
public void serialize(
- List<Rule> rules, Optional<Integer> formatVersion, OutputStream outputStream) {
- // TODO: Implement stream serializer.
+ List<Rule> rules, Optional<Integer> formatVersion, OutputStream outputStream)
+ throws RuleSerializeException {
+ try {
+ BitOutputStream bitOutputStream = new BitOutputStream();
+
+ int formatVersionValue = formatVersion.orElse(DEFAULT_FORMAT_VERSION);
+ bitOutputStream.setNext(FORMAT_VERSION_BITS, formatVersionValue);
+ outputStream.write(bitOutputStream.toByteArray());
+
+ for (Rule rule : rules) {
+ bitOutputStream.clear();
+ serializeRule(rule, bitOutputStream);
+ outputStream.write(bitOutputStream.toByteArray());
+ }
+ } catch (Exception e) {
+ throw new RuleSerializeException(e.getMessage(), e);
+ }
}
+ // Get the byte representation for a list of rules.
@Override
- public byte[] serialize(List<Rule> rules, Optional<Integer> formatVersion) {
- // TODO: Implement text serializer.
- return null;
+ public byte[] serialize(List<Rule> rules, Optional<Integer> formatVersion)
+ throws RuleSerializeException {
+ try {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ serialize(rules, formatVersion, byteArrayOutputStream);
+ return byteArrayOutputStream.toByteArray();
+ } catch (Exception e) {
+ throw new RuleSerializeException(e.getMessage(), e);
+ }
+ }
+
+ private void serializeRule(Rule rule, BitOutputStream bitOutputStream) {
+ if (rule == null) {
+ throw new IllegalArgumentException("Null rule can not be serialized");
+ }
+
+ // Start with a '1' bit to mark the start of a rule.
+ bitOutputStream.setNext();
+
+ serializeFormula(rule.getFormula(), bitOutputStream);
+ bitOutputStream.setNext(EFFECT_BITS, rule.getEffect());
+
+ // End with a '1' bit to mark the end of a rule.
+ bitOutputStream.setNext();
+ }
+
+ private void serializeFormula(Formula formula, BitOutputStream bitOutputStream) {
+ if (formula instanceof AtomicFormula) {
+ serializeAtomicFormula((AtomicFormula) formula, bitOutputStream);
+ } else if (formula instanceof CompoundFormula) {
+ serializeCompoundFormula((CompoundFormula) formula, bitOutputStream);
+ } else {
+ throw new IllegalArgumentException(
+ String.format("Invalid formula type: %s", formula.getClass()));
+ }
+ }
+
+ private void serializeCompoundFormula(
+ CompoundFormula compoundFormula, BitOutputStream bitOutputStream) {
+ if (compoundFormula == null) {
+ throw new IllegalArgumentException("Null compound formula can not be serialized");
+ }
+
+ bitOutputStream.setNext(SEPARATOR_BITS, COMPOUND_FORMULA_START);
+ bitOutputStream.setNext(CONNECTOR_BITS, compoundFormula.getConnector());
+ for (Formula formula : compoundFormula.getFormulas()) {
+ serializeFormula(formula, bitOutputStream);
+ }
+ bitOutputStream.setNext(SEPARATOR_BITS, COMPOUND_FORMULA_END);
+ }
+
+ private void serializeAtomicFormula(
+ AtomicFormula atomicFormula, BitOutputStream bitOutputStream) {
+ if (atomicFormula == null) {
+ throw new IllegalArgumentException("Null atomic formula can not be serialized");
+ }
+
+ bitOutputStream.setNext(SEPARATOR_BITS, ATOMIC_FORMULA_START);
+ bitOutputStream.setNext(KEY_BITS, atomicFormula.getKey());
+ if (atomicFormula instanceof AtomicFormula.StringAtomicFormula) {
+ AtomicFormula.StringAtomicFormula stringAtomicFormula =
+ (AtomicFormula.StringAtomicFormula) atomicFormula;
+ bitOutputStream.setNext(OPERATOR_BITS, AtomicFormula.EQ);
+ serializeValue(
+ stringAtomicFormula.getValue(),
+ stringAtomicFormula.getIsHashedValue(),
+ bitOutputStream);
+ } else if (atomicFormula instanceof AtomicFormula.IntAtomicFormula) {
+ AtomicFormula.IntAtomicFormula intAtomicFormula =
+ (AtomicFormula.IntAtomicFormula) atomicFormula;
+ bitOutputStream.setNext(OPERATOR_BITS, intAtomicFormula.getOperator());
+ serializeValue(
+ String.valueOf(intAtomicFormula.getValue()),
+ /* isHashedValue= */ false,
+ bitOutputStream);
+ } else if (atomicFormula instanceof AtomicFormula.BooleanAtomicFormula) {
+ AtomicFormula.BooleanAtomicFormula booleanAtomicFormula =
+ (AtomicFormula.BooleanAtomicFormula) atomicFormula;
+ bitOutputStream.setNext(OPERATOR_BITS, AtomicFormula.EQ);
+ serializeValue(
+ booleanAtomicFormula.getValue() ? "1" : "0",
+ /* isHashedValue= */ false,
+ bitOutputStream);
+ } else {
+ throw new IllegalArgumentException(
+ String.format("Invalid atomic formula type: %s", atomicFormula.getClass()));
+ }
+ }
+
+ private void serializeValue(
+ String value, boolean isHashedValue, BitOutputStream bitOutputStream) {
+ byte[] valueBytes = value.getBytes(StandardCharsets.UTF_8);
+
+ bitOutputStream.setNext(isHashedValue);
+ bitOutputStream.setNext(VALUE_SIZE_BITS, valueBytes.length);
+ for (byte valueByte : valueBytes) {
+ bitOutputStream.setNext(/* numOfBits= */ 8, valueByte);
+ }
}
}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
index 3ec9cf2..72068ce 100644
--- a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
+++ b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
@@ -39,7 +39,7 @@
private static final String RULE_LIST_TAG = "RL";
private static final String RULE_TAG = "R";
- private static final String OPEN_FORMULA_TAG = "OF";
+ private static final String COMPOUND_FORMULA_TAG = "OF";
private static final String ATOMIC_FORMULA_TAG = "AF";
private static final String EFFECT_ATTRIBUTE = "E";
private static final String KEY_ATTRIBUTE = "K";
@@ -78,13 +78,13 @@
private void serializeRules(List<Rule> rules, XmlSerializer xmlSerializer) throws IOException {
xmlSerializer.startTag(NAMESPACE, RULE_LIST_TAG);
for (Rule rule : rules) {
- serialize(rule, xmlSerializer);
+ serializeRule(rule, xmlSerializer);
}
xmlSerializer.endTag(NAMESPACE, RULE_LIST_TAG);
xmlSerializer.endDocument();
}
- private void serialize(Rule rule, XmlSerializer xmlSerializer) throws IOException {
+ private void serializeRule(Rule rule, XmlSerializer xmlSerializer) throws IOException {
if (rule == null) {
return;
}
@@ -98,25 +98,25 @@
if (formula instanceof AtomicFormula) {
serializeAtomicFormula((AtomicFormula) formula, xmlSerializer);
} else if (formula instanceof CompoundFormula) {
- serializeOpenFormula((CompoundFormula) formula, xmlSerializer);
+ serializeCompoundFormula((CompoundFormula) formula, xmlSerializer);
} else {
throw new IllegalArgumentException(
String.format("Invalid formula type: %s", formula.getClass()));
}
}
- private void serializeOpenFormula(CompoundFormula compoundFormula, XmlSerializer xmlSerializer)
- throws IOException {
+ private void serializeCompoundFormula(
+ CompoundFormula compoundFormula, XmlSerializer xmlSerializer) throws IOException {
if (compoundFormula == null) {
return;
}
- xmlSerializer.startTag(NAMESPACE, OPEN_FORMULA_TAG);
+ xmlSerializer.startTag(NAMESPACE, COMPOUND_FORMULA_TAG);
serializeAttributeValue(
CONNECTOR_ATTRIBUTE, String.valueOf(compoundFormula.getConnector()), xmlSerializer);
for (Formula formula : compoundFormula.getFormulas()) {
serializeFormula(formula, xmlSerializer);
}
- xmlSerializer.endTag(NAMESPACE, OPEN_FORMULA_TAG);
+ xmlSerializer.endTag(NAMESPACE, COMPOUND_FORMULA_TAG);
}
private void serializeAtomicFormula(AtomicFormula atomicFormula, XmlSerializer xmlSerializer)
diff --git a/services/core/java/com/android/server/net/NetworkIdentitySet.java b/services/core/java/com/android/server/net/NetworkIdentitySet.java
index 68cd5e7..2326ad3 100644
--- a/services/core/java/com/android/server/net/NetworkIdentitySet.java
+++ b/services/core/java/com/android/server/net/NetworkIdentitySet.java
@@ -170,11 +170,11 @@
return ident.compareTo(anotherIdent);
}
- public void writeToProto(ProtoOutputStream proto, long tag) {
+ public void dumpDebug(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
for (NetworkIdentity ident : this) {
- ident.writeToProto(proto, NetworkIdentitySetProto.IDENTITIES);
+ ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES);
}
proto.end(start);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index dfdc2c1..82d74bc 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -222,7 +222,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.DumpUtils;
@@ -1656,10 +1655,10 @@
// No need to do a permission check, because the ACTION_CARRIER_CONFIG_CHANGED
// broadcast is protected and can't be spoofed. Runs on a background handler thread.
- if (!intent.hasExtra(PhoneConstants.SUBSCRIPTION_KEY)) {
+ if (!intent.hasExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX)) {
return;
}
- final int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, -1);
+ final int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, -1);
// Get all of our cross-process communication with telephony out of
// the way before we acquire internal locks.
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index ab52523..05ab2ae 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -687,7 +687,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long tag) {
+ public void dumpDebug(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
for (Key key : getSortedKeys()) {
@@ -695,7 +695,7 @@
// Key
final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY);
- key.ident.writeToProto(proto, NetworkStatsCollectionKeyProto.IDENTITY);
+ key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY);
proto.write(NetworkStatsCollectionKeyProto.UID, key.uid);
proto.write(NetworkStatsCollectionKeyProto.SET, key.set);
proto.write(NetworkStatsCollectionKeyProto.TAG, key.tag);
@@ -703,7 +703,7 @@
// Value
final NetworkStatsHistory history = mStats.get(key);
- history.writeToProto(proto, NetworkStatsCollectionStatsProto.HISTORY);
+ history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY);
proto.end(startStats);
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsRecorder.java b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
index 06ec341..6af962b 100644
--- a/services/core/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
@@ -470,12 +470,12 @@
}
}
- public void writeToProtoLocked(ProtoOutputStream proto, long tag) {
+ public void dumpDebugLocked(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
if (mPending != null) {
proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES, mPending.getTotalBytes());
}
- getOrLoadCompleteLocked().writeToProto(proto, NetworkStatsRecorderProto.COMPLETE_HISTORY);
+ getOrLoadCompleteLocked().dumpDebug(proto, NetworkStatsRecorderProto.COMPLETE_HISTORY);
proto.end(start);
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 16424f2..673e830 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -1609,10 +1609,10 @@
dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
- mDevRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
- mXtRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
- mUidRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
- mUidTagRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
+ mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
+ mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
+ mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
+ mUidTagRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
proto.flush();
}
@@ -1623,7 +1623,7 @@
final long start = proto.start(tag);
proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
- ifaces.valueAt(i).writeToProto(proto, NetworkInterfaceProto.IDENTITIES);
+ ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES);
proto.end(start);
}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 8560ae6..45df368 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -379,18 +379,18 @@
for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
if (filter != null && !filter.matches(cmpt)) continue;
- cmpt.writeToProto(proto, ManagedServicesProto.ENABLED);
+ cmpt.dumpDebug(proto, ManagedServicesProto.ENABLED);
}
synchronized (mMutex) {
for (ManagedServiceInfo info : mServices) {
if (filter != null && !filter.matches(info.component)) continue;
- info.writeToProto(proto, ManagedServicesProto.LIVE_SERVICES, this);
+ info.dumpDebug(proto, ManagedServicesProto.LIVE_SERVICES, this);
}
}
for (ComponentName name : mSnoozingForCurrentProfiles) {
- name.writeToProto(proto, ManagedServicesProto.SNOOZED);
+ name.dumpDebug(proto, ManagedServicesProto.SNOOZED);
}
}
@@ -1497,9 +1497,9 @@
.append(']').toString();
}
- public void writeToProto(ProtoOutputStream proto, long fieldId, ManagedServices host) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, ManagedServices host) {
final long token = proto.start(fieldId);
- component.writeToProto(proto, ManagedServiceInfoProto.COMPONENT);
+ component.dumpDebug(proto, ManagedServiceInfoProto.COMPONENT);
proto.write(ManagedServiceInfoProto.USER_ID, userid);
proto.write(ManagedServiceInfoProto.SERVICE, service.getClass().getName());
proto.write(ManagedServiceInfoProto.IS_SYSTEM, isSystem);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 293fd40..d0ad47d 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4802,7 +4802,7 @@
long zenLog = proto.start(NotificationServiceDumpProto.ZEN);
mZenModeHelper.dump(proto);
for (ComponentName suppressor : mEffectsSuppressors) {
- suppressor.writeToProto(proto, ZenModeProto.SUPPRESSORS);
+ suppressor.dumpDebug(proto, ZenModeProto.SUPPRESSORS);
}
proto.end(zenLog);
@@ -4822,7 +4822,7 @@
mListenersDisablingEffects.valueAt(i);
for (int j = 0; j < listeners.size(); j++) {
final ComponentName componentName = listeners.valueAt(j);
- componentName.writeToProto(proto,
+ componentName.dumpDebug(proto,
ListenersDisablingEffectsProto.LISTENER_COMPONENTS);
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index a126073..b57bfa0 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -434,7 +434,7 @@
proto.write(NotificationRecordProto.SOUND, getSound().toString());
}
if (getAudioAttributes() != null) {
- getAudioAttributes().writeToProto(proto, NotificationRecordProto.AUDIO_ATTRIBUTES);
+ getAudioAttributes().dumpDebug(proto, NotificationRecordProto.AUDIO_ATTRIBUTES);
}
proto.write(NotificationRecordProto.PACKAGE, sbn.getPackageName());
proto.write(NotificationRecordProto.DELEGATE_PACKAGE, sbn.getOpPkg());
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index cbbf2a0..b1ffa8c 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -1564,10 +1564,10 @@
proto.write(RankingHelperProto.RecordProto.SHOW_BADGE, r.showBadge);
for (NotificationChannel channel : r.channels.values()) {
- channel.writeToProto(proto, RankingHelperProto.RecordProto.CHANNELS);
+ channel.dumpDebug(proto, RankingHelperProto.RecordProto.CHANNELS);
}
for (NotificationChannelGroup group : r.groups.values()) {
- group.writeToProto(proto, RankingHelperProto.RecordProto.CHANNEL_GROUPS);
+ group.dumpDebug(proto, RankingHelperProto.RecordProto.CHANNEL_GROUPS);
}
proto.end(fToken);
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 6510923..696d2ea 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -627,15 +627,15 @@
proto.write(ZenModeProto.ZEN_MODE, mZenMode);
synchronized (mConfig) {
if (mConfig.manualRule != null) {
- mConfig.manualRule.writeToProto(proto, ZenModeProto.ENABLED_ACTIVE_CONDITIONS);
+ mConfig.manualRule.dumpDebug(proto, ZenModeProto.ENABLED_ACTIVE_CONDITIONS);
}
for (ZenRule rule : mConfig.automaticRules.values()) {
if (rule.enabled && rule.condition.state == Condition.STATE_TRUE
&& !rule.snoozing) {
- rule.writeToProto(proto, ZenModeProto.ENABLED_ACTIVE_CONDITIONS);
+ rule.dumpDebug(proto, ZenModeProto.ENABLED_ACTIVE_CONDITIONS);
}
}
- mConfig.toNotificationPolicy().writeToProto(proto, ZenModeProto.POLICY);
+ mConfig.toNotificationPolicy().dumpDebug(proto, ZenModeProto.POLICY);
proto.write(ZenModeProto.SUPPRESSED_EFFECTS, mSuppressedEffects);
}
}
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index ec11a97..14ef2d3a 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -136,8 +136,11 @@
DeviceConfig.addOnPropertiesChangedListener(
NAMESPACE_PACKAGE_MANAGER_SERVICE, FgThread.getExecutor(),
properties -> {
- synchronized (FeatureConfigImpl.this) {
- mFeatureEnabled = properties.getBoolean(FILTERING_ENABLED_NAME, false);
+ if (properties.getKeyset().contains(FILTERING_ENABLED_NAME)) {
+ synchronized (FeatureConfigImpl.this) {
+ mFeatureEnabled = properties.getBoolean(FILTERING_ENABLED_NAME,
+ false);
+ }
}
});
}
diff --git a/services/core/java/com/android/server/pm/DataLoaderManagerService.java b/services/core/java/com/android/server/pm/DataLoaderManagerService.java
new file mode 100644
index 0000000..0719797
--- /dev/null
+++ b/services/core/java/com/android/server/pm/DataLoaderManagerService.java
@@ -0,0 +1,246 @@
+/*
+ * 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.server.pm;
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IDataLoader;
+import android.content.pm.IDataLoaderManager;
+import android.content.pm.IDataLoaderStatusListener;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.SystemService;
+
+import java.util.List;
+
+/**
+ * Data loader manager service manages data loader binder services.
+ *
+ * @hide
+ */
+public class DataLoaderManagerService extends SystemService {
+ private static final String TAG = "DataLoaderManager";
+ private final Context mContext;
+ private final DataLoaderManagerBinderService mBinderService;
+ private final Object mLock = new Object();
+ @GuardedBy("mLock")
+ private SparseArray<DataLoaderServiceConnection> mServiceConnections;
+
+ public DataLoaderManagerService(Context context) {
+ super(context);
+ mContext = context;
+ mBinderService = new DataLoaderManagerBinderService();
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(Context.DATA_LOADER_MANAGER_SERVICE, mBinderService);
+ }
+
+ final class DataLoaderManagerBinderService extends IDataLoaderManager.Stub {
+ @Override
+ public boolean initializeDataLoader(int dataLoaderId, Bundle params,
+ IDataLoaderStatusListener listener) {
+ synchronized (mLock) {
+ if (mServiceConnections == null) {
+ mServiceConnections = new SparseArray<>();
+ }
+ if (mServiceConnections.get(dataLoaderId) != null) {
+ Slog.e(TAG, "Data loader of ID=" + dataLoaderId + " already exists.");
+ return false;
+ }
+ }
+ CharSequence packageNameSeq = params.getCharSequence("packageName");
+ if (packageNameSeq == null) {
+ Slog.e(TAG, "Must specify package name.");
+ return false;
+ }
+ String packageName = packageNameSeq.toString();
+ ComponentName dataLoaderComponent = getDataLoaderServiceName(packageName);
+ if (dataLoaderComponent == null) {
+ return false;
+ }
+ // Binds to the specific data loader service
+ DataLoaderServiceConnection connection =
+ new DataLoaderServiceConnection(dataLoaderId, params, 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.");
+ mContext.unbindService(connection);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Find the ComponentName of the data loader service provider, given its package name.
+ *
+ * @param packageName the package name of the provider.
+ * @return ComponentName of the data loader service provider. Null if provider not found.
+ */
+ private @Nullable ComponentName getDataLoaderServiceName(String packageName) {
+ final PackageManager pm = mContext.getPackageManager();
+ if (pm == null) {
+ Slog.e(TAG, "PackageManager is not available.");
+ return null;
+ }
+ Intent intent = new Intent(Intent.ACTION_LOAD_DATA);
+ intent.setPackage(packageName);
+ List<ResolveInfo> services =
+ pm.queryIntentServicesAsUser(intent, 0, UserHandle.getCallingUserId());
+ if (services == null || services.isEmpty()) {
+ Slog.e(TAG,
+ "Failed to find data loader service provider in package " + packageName);
+ return null;
+ }
+
+ // TODO(b/136132412): better way to enable privileged data loaders in tests
+ boolean checkLoader =
+ android.os.SystemProperties.getBoolean("incremental.check_loader", false);
+ int numServices = services.size();
+ for (int i = 0; i < numServices; i++) {
+ ResolveInfo ri = services.get(i);
+ ComponentName componentName = new ComponentName(
+ ri.serviceInfo.packageName, ri.serviceInfo.name);
+ // There should only be one matching provider inside the given package.
+ // If there's more than one, return the first one found.
+ try {
+ ApplicationInfo ai = pm.getApplicationInfo(componentName.getPackageName(), 0);
+ if (checkLoader && !ai.isPrivilegedApp()) {
+ Slog.w(TAG,
+ "Data loader: " + componentName.getPackageName()
+ + " is not a privileged app, skipping.");
+ continue;
+ }
+ return componentName;
+ } catch (PackageManager.NameNotFoundException ex) {
+ Slog.w(TAG,
+ "Privileged data loader: " + componentName.getPackageName()
+ + " not found, skipping.");
+ }
+
+ }
+ Slog.e(TAG, "Didn't find any matching data loader service provider.");
+ return null;
+ }
+
+ /**
+ * Returns the binder object of a data loader, specified by its ID.
+ */
+ @Override
+ public @Nullable IDataLoader getDataLoader(int dataLoaderId) {
+ synchronized (mLock) {
+ if (mServiceConnections == null) {
+ return null;
+ }
+ DataLoaderServiceConnection serviceConnection = mServiceConnections.get(
+ dataLoaderId, null);
+ if (serviceConnection == null) {
+ return null;
+ }
+ return serviceConnection.getDataLoader();
+ }
+ }
+
+ /**
+ * Destroys a data loader binder service, specified by its ID.
+ */
+ @Override
+ public void destroyDataLoader(int dataLoaderId) {
+ synchronized (mLock) {
+ if (mServiceConnections == null) {
+ return;
+ }
+ DataLoaderServiceConnection serviceConnection = mServiceConnections.get(
+ dataLoaderId, null);
+
+ if (serviceConnection == null) {
+ return;
+ }
+ serviceConnection.destroy();
+ }
+ }
+ }
+
+ class DataLoaderServiceConnection implements ServiceConnection {
+ final int mId;
+ final Bundle mParams;
+ final IDataLoaderStatusListener mListener;
+ IDataLoader mDataLoader;
+
+ DataLoaderServiceConnection(int id, Bundle params, IDataLoaderStatusListener listener) {
+ mId = id;
+ mParams = params;
+ mListener = listener;
+ mDataLoader = null;
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ mDataLoader = IDataLoader.Stub.asInterface(service);
+ synchronized (mLock) {
+ mServiceConnections.append(mId, this);
+ }
+ try {
+ mDataLoader.create(mId, mParams, mListener);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to create data loader service.", e);
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName arg0) {
+ remove();
+ }
+
+ IDataLoader getDataLoader() {
+ return mDataLoader;
+ }
+
+ void destroy() {
+ try {
+ mDataLoader.destroy();
+ } catch (RemoteException ignored) {
+ }
+ mContext.unbindService(this);
+ }
+
+ private void remove() {
+ synchronized (mLock) {
+ mServiceConnections.remove(mId);
+ if (mServiceConnections.size() == 0) {
+ mServiceConnections = null;
+ }
+ }
+ mParams.clear();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 4852947..883baf7 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -54,6 +54,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageInstallerSession;
+import android.content.pm.InstallationFile;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
@@ -81,6 +82,8 @@
import android.os.RevocableFileDescriptor;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.incremental.IncrementalFileStorages;
+import android.os.incremental.IncrementalManager;
import android.os.storage.StorageManager;
import android.stats.devicepolicy.DevicePolicyEnums;
import android.system.ErrnoException;
@@ -309,6 +312,8 @@
@GuardedBy("mLock")
private boolean mVerityFound;
+ private IncrementalFileStorages mIncrementalFileStorages;
+
private static final FileFilter sAddedFilter = new FileFilter() {
@Override
public boolean accept(File file) {
@@ -471,6 +476,18 @@
mStagedSessionErrorCode = stagedSessionErrorCode;
mStagedSessionErrorMessage =
stagedSessionErrorMessage != null ? stagedSessionErrorMessage : "";
+
+ // TODO(b/136132412): sanity check if session should not be incremental
+ if (!params.isStaged && params.incrementalParams != null
+ && !params.incrementalParams.getPackageName().isEmpty()) {
+ IncrementalManager incrementalManager = (IncrementalManager) mContext.getSystemService(
+ Context.INCREMENTAL_SERVICE);
+ if (incrementalManager != null) {
+ mIncrementalFileStorages =
+ new IncrementalFileStorages(mPackageName, stageDir, incrementalManager,
+ params.incrementalParams);
+ }
+ }
}
public SessionInfo generateInfo() {
@@ -874,10 +891,18 @@
}
}
+ if (mIncrementalFileStorages != null) {
+ mIncrementalFileStorages.finishSetUp();
+ }
+
mHandler.obtainMessage(MSG_SEAL, statusReceiver).sendToTarget();
}
private void handleSeal(@NonNull IntentSender statusReceiver) {
+ // TODO(b/136132412): update with new APIs
+ if (mIncrementalFileStorages != null) {
+ mIncrementalFileStorages.startLoading();
+ }
if (!markAsCommitted(statusReceiver)) {
return;
}
@@ -1492,6 +1517,7 @@
computeProgressLocked(true);
// Unpack native libraries
+ // TODO(b/136132412): skip for incremental installation
extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs());
}
@@ -2182,7 +2208,6 @@
}
destroyInternal();
}
-
dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
}
@@ -2268,6 +2293,20 @@
return mParentSessionId;
}
+ @Override
+ public void addFile(@NonNull String name, long size, @NonNull byte[] metadata) {
+ if (mIncrementalFileStorages == null) {
+ throw new IllegalStateException(
+ "Cannot add Incremental File to a non-Incremental session.");
+ }
+ try {
+ mIncrementalFileStorages.addFile(new InstallationFile(name, size, metadata));
+ } catch (IOException ex) {
+ throw new IllegalStateException(
+ "Failed to add and configure Incremental File: " + name, ex);
+ }
+ }
+
private void dispatchSessionFinished(int returnCode, String msg, Bundle extras) {
final IntentSender statusReceiver;
final String packageName;
@@ -2390,6 +2429,9 @@
// since these packages are supposed to be read on reboot.
// Those dirs are deleted when the staged session has reached a final state.
if (stageDir != null && !params.isStaged) {
+ if (mIncrementalFileStorages != null) {
+ mIncrementalFileStorages.cleanUp();
+ }
try {
mPm.mInstaller.rmPackageDir(stageDir.getAbsolutePath());
} catch (InstallerException ignored) {
@@ -2403,6 +2445,9 @@
mSessionProvider.getSession(childSessionId).cleanStageDir();
}
} else {
+ if (mIncrementalFileStorages != null) {
+ mIncrementalFileStorages.cleanUp();
+ }
try {
mPm.mInstaller.rmPackageDir(stageDir.getAbsolutePath());
} catch (InstallerException ignored) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4e0e4ff..3d4247e7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -153,6 +153,7 @@
import android.content.pm.IPackageManagerNative;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
+import android.content.pm.InstallSourceInfo;
import android.content.pm.InstantAppInfo;
import android.content.pm.InstantAppRequest;
import android.content.pm.InstrumentationInfo;
@@ -20128,19 +20129,95 @@
public String getInstallerPackageName(String packageName) {
final int callingUid = Binder.getCallingUid();
synchronized (mLock) {
- final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (shouldFilterApplicationLocked(
- ps, callingUid, UserHandle.getUserId(callingUid))) {
- return null;
+ final InstallSource installSource = getInstallSourceLocked(packageName, callingUid);
+ if (installSource == null) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
}
- // InstallerPackageName for Apex is not stored in PackageManager
- if (ps == null && mApexManager.isApexPackage(packageName)) {
- return null;
+ String installerPackageName = installSource.installerPackageName;
+ if (installerPackageName != null) {
+ final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
+ if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
+ UserHandle.getUserId(callingUid))) {
+ installerPackageName = null;
+ }
}
- return mSettings.getInstallerPackageNameLPr(packageName);
+ return installerPackageName;
}
}
+ @Override
+ @Nullable
+ public InstallSourceInfo getInstallSourceInfo(String packageName) {
+ final int callingUid = Binder.getCallingUid();
+ final int userId = UserHandle.getUserId(callingUid);
+
+ String installerPackageName;
+ String initiatingPackageName;
+ String originatingPackageName;
+
+ synchronized (mLock) {
+ final InstallSource installSource = getInstallSourceLocked(packageName, callingUid);
+ if (installSource == null) {
+ return null;
+ }
+
+ installerPackageName = installSource.installerPackageName;
+ if (installerPackageName != null) {
+ final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
+ if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
+ installerPackageName = null;
+ }
+ }
+
+ // All installSource strings are interned, so == is ok here
+ if (installSource.initiatingPackageName == installSource.installerPackageName) {
+ // The installer and initiator will often be the same, and when they are
+ // we can skip doing the same check again.
+ initiatingPackageName = installerPackageName;
+ } else {
+ initiatingPackageName = installSource.initiatingPackageName;
+ final PackageSetting ps = mSettings.mPackages.get(initiatingPackageName);
+ if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
+ initiatingPackageName = null;
+ }
+
+ }
+ originatingPackageName = installSource.originatingPackageName;
+ if (originatingPackageName != null) {
+ final PackageSetting ps = mSettings.mPackages.get(originatingPackageName);
+ if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
+ originatingPackageName = null;
+ }
+ }
+ }
+
+ if (originatingPackageName != null && mContext.checkCallingOrSelfPermission(
+ Manifest.permission.INSTALL_PACKAGES) != PackageManager.PERMISSION_GRANTED) {
+ originatingPackageName = null;
+ }
+
+ return new InstallSourceInfo(initiatingPackageName, originatingPackageName,
+ installerPackageName);
+ }
+
+ @GuardedBy("mLock")
+ @Nullable
+ private InstallSource getInstallSourceLocked(String packageName, int callingUid) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+
+ // Installer info for Apex is not stored in PackageManager
+ if (ps == null && mApexManager.isApexPackage(packageName)) {
+ return InstallSource.EMPTY;
+ }
+
+ if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
+ UserHandle.getUserId(callingUid))) {
+ return null;
+ }
+
+ return ps.installSource;
+ }
+
public boolean isOrphaned(String packageName) {
// reader
synchronized (mLock) {
@@ -21050,7 +21127,7 @@
synchronized (mAvailableFeatures) {
final int count = mAvailableFeatures.size();
for (int i = 0; i < count; i++) {
- mAvailableFeatures.valueAt(i).writeToProto(proto, PackageServiceDumpProto.FEATURES);
+ mAvailableFeatures.valueAt(i).dumpDebug(proto, PackageServiceDumpProto.FEATURES);
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 1b73602..b961096 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1854,22 +1854,23 @@
if (internal.isApexPackage(packageName)) {
internal.uninstallApex(
packageName, versionCode, translatedUserId, receiver.getIntentSender(), flags);
- } else if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
- final PackageInfo info = mInterface.getPackageInfo(packageName,
- PackageManager.MATCH_STATIC_SHARED_LIBRARIES, translatedUserId);
- if (info == null) {
- pw.println("Failure [not installed for " + translatedUserId + "]");
- return 1;
+ } else {
+ if ((flags & PackageManager.DELETE_ALL_USERS) == 0) {
+ final PackageInfo info = mInterface.getPackageInfo(packageName,
+ PackageManager.MATCH_STATIC_SHARED_LIBRARIES, translatedUserId);
+ if (info == null) {
+ pw.println("Failure [not installed for " + translatedUserId + "]");
+ return 1;
+ }
+ final boolean isSystem =
+ (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ // If we are being asked to delete a system app for just one
+ // user set flag so it disables rather than reverting to system
+ // version of the app.
+ if (isSystem) {
+ flags |= PackageManager.DELETE_SYSTEM_APP;
+ }
}
- final boolean isSystem =
- (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
- // If we are being asked to delete a system app for just one
- // user set flag so it disables rather than reverting to system
- // version of the app.
- if (isSystem) {
- flags |= PackageManager.DELETE_SYSTEM_APP;
- }
-
mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
versionCode), null /*callerPackageName*/, flags,
receiver.getIntentSender(), translatedUserId);
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 1254891..d38dd93 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -180,7 +180,7 @@
return childPackageNames != null && !childPackageNames.isEmpty();
}
- public void writeToProto(ProtoOutputStream proto, long fieldId, List<UserInfo> users) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId, List<UserInfo> users) {
final long packageToken = proto.start(fieldId);
proto.write(PackageProto.NAME, (realName != null ? realName : name));
proto.write(PackageProto.UID, appId);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index f67d3c0..1082eaa 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4257,14 +4257,6 @@
return userState.isMatch(componentInfo, flags);
}
- String getInstallerPackageNameLPr(String packageName) {
- final PackageSetting pkg = mPackages.get(packageName);
- if (pkg == null) {
- throw new IllegalArgumentException("Unknown package: " + packageName);
- }
- return pkg.installSource.installerPackageName;
- }
-
boolean isOrphaned(String packageName) {
final PackageSetting pkg = mPackages.get(packageName);
if (pkg == null) {
@@ -4942,7 +4934,7 @@
final int count = mPackages.size();
for (int i = 0; i < count; i++) {
final PackageSetting ps = mPackages.valueAt(i);
- ps.writeToProto(proto, PackageServiceDumpProto.PACKAGES, users);
+ ps.dumpDebug(proto, PackageServiceDumpProto.PACKAGES, users);
}
}
@@ -5018,7 +5010,7 @@
void dumpSharedUsersProto(ProtoOutputStream proto) {
final int count = mSharedUsers.size();
for (int i = 0; i < count; i++) {
- mSharedUsers.valueAt(i).writeToProto(proto, PackageServiceDumpProto.SHARED_USERS);
+ mSharedUsers.valueAt(i).dumpDebug(proto, PackageServiceDumpProto.SHARED_USERS);
}
}
diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java
index 2ee07a2..6480518 100644
--- a/services/core/java/com/android/server/pm/SharedUserSetting.java
+++ b/services/core/java/com/android/server/pm/SharedUserSetting.java
@@ -65,7 +65,7 @@
+ name + "/" + userId + "}";
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(PackageServiceDumpProto.SharedUserProto.UID, userId);
proto.write(PackageServiceDumpProto.SharedUserProto.NAME, name);
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 3c4e3f6..9b9f93f 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -29,10 +29,8 @@
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
-import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -171,23 +169,6 @@
} catch (RemoteException doesNotHappen) {
Slog.wtf(LOG_TAG, "Cannot set up app-ops listener");
}
-
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
- intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
- intentFilter.addDataScheme("package");
-
- getContext().registerReceiverAsUser(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- UserHandle user =
- UserHandle.getUserHandleForUid(intent.getIntExtra(Intent.EXTRA_UID, -1));
- new PermissionControllerManager(
- getUserContext(getContext(), user), FgThread.getHandler())
- .updateUserSensitive();
- }
- }, UserHandle.ALL, intentFilter, null, null);
-
}
/**
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 3e528f4..8435a82 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5432,7 +5432,7 @@
}
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(ROTATION_MODE, mDefaultDisplayRotation.getUserRotationMode());
proto.write(ROTATION, mDefaultDisplayRotation.getUserRotation());
@@ -5445,7 +5445,7 @@
proto.write(KEYGUARD_OCCLUDED_CHANGED, mKeyguardOccludedChanged);
proto.write(KEYGUARD_OCCLUDED_PENDING, mPendingKeyguardOccluded);
if (mKeyguardDelegate != null) {
- mKeyguardDelegate.writeToProto(proto, KEYGUARD_DELEGATE);
+ mKeyguardDelegate.dumpDebug(proto, KEYGUARD_DELEGATE);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 1f37faf..95a5f52 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -1404,7 +1404,7 @@
*
* @param proto The protocol buffer output stream to write to.
*/
- void writeToProto(ProtoOutputStream proto, long fieldId);
+ void dumpDebug(ProtoOutputStream proto, long fieldId);
/**
* Returns whether a given window type is considered a top level one.
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 47370b6..0157706 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -259,7 +259,7 @@
*/
public abstract void onProposedRotationChanged(int rotation);
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
synchronized (mLock) {
proto.write(ENABLED, mEnabled);
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index c408549..9b67efe 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -413,7 +413,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(SHOWING, mKeyguardState.showing);
proto.write(OCCLUDED, mKeyguardState.occluded);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 114a16a..93d50b8 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -203,8 +203,11 @@
// System Property indicating that retail demo mode is currently enabled.
private static final String SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED = "sys.retaildemo.enabled";
- // Possible reasons for shutting down or reboot for use in REBOOT_PROPERTY(sys.boot.reason)
- // which is set by bootstat
+ // System property for last reboot reason
+ private static final String SYSTEM_PROPERTY_REBOOT_REASON = "sys.boot.reason";
+
+ // Possible reasons for shutting down or reboot for use in
+ // SYSTEM_PROPERTY_REBOOT_REASON(sys.boot.reason) which is set by bootstat
private static final String REASON_SHUTDOWN = "shutdown";
private static final String REASON_REBOOT = "reboot";
private static final String REASON_USERREQUESTED = "shutdown,userrequested";
@@ -225,9 +228,6 @@
private static final int HALT_MODE_REBOOT = 1;
private static final int HALT_MODE_REBOOT_SAFE_MODE = 2;
- // property for last reboot reason
- private static final String REBOOT_PROPERTY = "sys.boot.reason";
-
private final Context mContext;
private final ServiceThread mHandlerThread;
private final PowerManagerHandler mHandler;
@@ -240,6 +240,7 @@
private final BinderService mBinderService;
private final LocalService mLocalService;
private final NativeWrapper mNativeWrapper;
+ private final SystemPropertiesWrapper mSystemProperties;
private final Injector mInjector;
private LightsManager mLightsManager;
@@ -756,6 +757,20 @@
InattentiveSleepWarningController createInattentiveSleepWarningController() {
return new InattentiveSleepWarningController();
}
+
+ public SystemPropertiesWrapper createSystemPropertiesWrapper() {
+ return new SystemPropertiesWrapper() {
+ @Override
+ public String get(String key, String def) {
+ return SystemProperties.get(key, def);
+ }
+
+ @Override
+ public void set(String key, String val) {
+ SystemProperties.set(key, val);
+ }
+ };
+ }
}
final Constants mConstants;
@@ -781,6 +796,7 @@
mBinderService = new BinderService();
mLocalService = new LocalService();
mNativeWrapper = injector.createNativeWrapper();
+ mSystemProperties = injector.createSystemPropertiesWrapper();
mInjector = injector;
mHandlerThread = new ServiceThread(TAG,
@@ -816,7 +832,7 @@
mHalInteractiveModeEnabled = true;
mWakefulness = WAKEFULNESS_AWAKE;
- sQuiescent = SystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1");
+ sQuiescent = mSystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1");
mNativeWrapper.nativeInit(this);
mNativeWrapper.nativeSetAutoSuspend(false);
@@ -1067,8 +1083,9 @@
}
final String retailDemoValue = UserManager.isDeviceInDemoMode(mContext) ? "1" : "0";
- if (!retailDemoValue.equals(SystemProperties.get(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED))) {
- SystemProperties.set(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, retailDemoValue);
+ if (!retailDemoValue.equals(
+ mSystemProperties.get(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, null))) {
+ mSystemProperties.set(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, retailDemoValue);
}
mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
@@ -4070,20 +4087,20 @@
mBatterySaverStateMachine.dumpProto(proto,
PowerManagerServiceDumpProto.BATTERY_SAVER_STATE_MACHINE);
- mHandler.getLooper().writeToProto(proto, PowerManagerServiceDumpProto.LOOPER);
+ mHandler.getLooper().dumpDebug(proto, PowerManagerServiceDumpProto.LOOPER);
for (WakeLock wl : mWakeLocks) {
- wl.writeToProto(proto, PowerManagerServiceDumpProto.WAKE_LOCKS);
+ wl.dumpDebug(proto, PowerManagerServiceDumpProto.WAKE_LOCKS);
}
for (SuspendBlocker sb : mSuspendBlockers) {
- sb.writeToProto(proto, PowerManagerServiceDumpProto.SUSPEND_BLOCKERS);
+ sb.dumpDebug(proto, PowerManagerServiceDumpProto.SUSPEND_BLOCKERS);
}
wcd = mWirelessChargerDetector;
}
if (wcd != null) {
- wcd.writeToProto(proto, PowerManagerServiceDumpProto.WIRELESS_CHARGER_DETECTOR);
+ wcd.dumpDebug(proto, PowerManagerServiceDumpProto.WIRELESS_CHARGER_DETECTOR);
}
proto.flush();
}
@@ -4314,7 +4331,7 @@
return sb.toString();
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long wakeLockToken = proto.start(fieldId);
proto.write(WakeLockProto.LOCK_LEVEL, (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK));
proto.write(WakeLockProto.TAG, mTag);
@@ -4335,7 +4352,7 @@
proto.write(WakeLockProto.PID, mOwnerPid);
if (mWorkSource != null) {
- mWorkSource.writeToProto(proto, WakeLockProto.WORK_SOURCE);
+ mWorkSource.dumpDebug(proto, WakeLockProto.WORK_SOURCE);
}
proto.end(wakeLockToken);
}
@@ -4438,7 +4455,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long sbToken = proto.start(fieldId);
synchronized (this) {
proto.write(SuspendBlockerProto.NAME, mName);
@@ -4820,7 +4837,7 @@
final long ident = Binder.clearCallingIdentity();
try {
- return getLastShutdownReasonInternal(REBOOT_PROPERTY);
+ return getLastShutdownReasonInternal();
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -5054,12 +5071,8 @@
}
@VisibleForTesting
- // lastRebootReasonProperty argument to permit testing
- int getLastShutdownReasonInternal(String lastRebootReasonProperty) {
- String line = SystemProperties.get(lastRebootReasonProperty);
- if (line == null) {
- return PowerManager.SHUTDOWN_REASON_UNKNOWN;
- }
+ int getLastShutdownReasonInternal() {
+ String line = mSystemProperties.get(SYSTEM_PROPERTY_REBOOT_REASON, null);
switch (line) {
case REASON_SHUTDOWN:
return PowerManager.SHUTDOWN_REASON_SHUTDOWN;
diff --git a/services/core/java/com/android/server/power/SuspendBlocker.java b/services/core/java/com/android/server/power/SuspendBlocker.java
index 30b35f0..565263f 100644
--- a/services/core/java/com/android/server/power/SuspendBlocker.java
+++ b/services/core/java/com/android/server/power/SuspendBlocker.java
@@ -43,5 +43,5 @@
*/
void release();
- void writeToProto(ProtoOutputStream proto, long fieldId);
+ void dumpDebug(ProtoOutputStream proto, long fieldId);
}
diff --git a/services/core/java/com/android/server/power/SystemPropertiesWrapper.java b/services/core/java/com/android/server/power/SystemPropertiesWrapper.java
new file mode 100644
index 0000000..1acf798
--- /dev/null
+++ b/services/core/java/com/android/server/power/SystemPropertiesWrapper.java
@@ -0,0 +1,51 @@
+/*
+ * 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.server.power;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.SystemProperties;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Wrapper interface to access {@link SystemProperties}.
+ *
+ * @hide
+ */
+@VisibleForTesting
+interface SystemPropertiesWrapper {
+ /**
+ * Get the String value for the given {@code key}.
+ *
+ * @param key the key to lookup
+ * @param def the default value in case the property is not set or empty
+ * @return if the {@code key} isn't found, return {@code def} if it isn't null, or an empty
+ * string otherwise
+ */
+ @NonNull
+ String get(@NonNull String key, @Nullable String def);
+
+ /**
+ * Set the value for the given {@code key} to {@code val}.
+ *
+ * @throws IllegalArgumentException if the {@code val} exceeds 91 characters
+ * @throws RuntimeException if the property cannot be set, for example, if it was blocked by
+ * SELinux. libc will log the underlying reason.
+ */
+ void set(@NonNull String key, @Nullable String val);
+}
diff --git a/services/core/java/com/android/server/power/WirelessChargerDetector.java b/services/core/java/com/android/server/power/WirelessChargerDetector.java
index e8e9c67..0d910e4 100644
--- a/services/core/java/com/android/server/power/WirelessChargerDetector.java
+++ b/services/core/java/com/android/server/power/WirelessChargerDetector.java
@@ -170,7 +170,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long wcdToken = proto.start(fieldId);
synchronized (mLock) {
proto.write(WirelessChargerDetectorProto.IS_POWERED_WIRELESSLY, mPoweredWirelessly);
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 00779ec..3f5e2a4 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -57,6 +57,7 @@
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
+import com.android.server.PackageWatchdog;
import com.android.server.Watchdog;
import com.android.server.pm.Installer;
@@ -1200,6 +1201,8 @@
for (Rollback rollback : mRollbacks) {
rollback.dump(ipw);
}
+ ipw.println();
+ PackageWatchdog.getInstance(mContext).dump(ipw);
}
}
diff --git a/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java
index 0b970bf..340fe3d 100644
--- a/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java
@@ -150,7 +150,8 @@
if (!mCallback.isAutoTimeDetectionEnabled()) {
if (DBG) {
Slog.d(LOG_TAG, "Auto time detection is not enabled."
- + " time=" + time
+ + " origin=" + origin
+ + ", time=" + time
+ ", cause=" + cause);
}
return;
@@ -159,7 +160,8 @@
if (mCallback.isAutoTimeDetectionEnabled()) {
if (DBG) {
Slog.d(LOG_TAG, "Auto time detection is enabled."
- + " time=" + time
+ + " origin=" + origin
+ + ", time=" + time
+ ", cause=" + cause);
}
return;
@@ -232,16 +234,16 @@
@Override
public synchronized void dump(@NonNull PrintWriter pw, @Nullable String[] args) {
- pw.println("mLastPhoneSuggestion=" + mLastPhoneSuggestion);
- pw.println("mLastAutoSystemClockTimeSet=" + mLastAutoSystemClockTimeSet);
- pw.println("mLastAutoSystemClockTime=" + mLastAutoSystemClockTime);
- pw.println("mLastAutoSystemClockTimeSendNetworkBroadcast="
+ IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ ipw.println("TimeDetectorStrategy:");
+ ipw.increaseIndent(); // level 1
+
+ ipw.println("mLastPhoneSuggestion=" + mLastPhoneSuggestion);
+ ipw.println("mLastAutoSystemClockTimeSet=" + mLastAutoSystemClockTimeSet);
+ ipw.println("mLastAutoSystemClockTime=" + mLastAutoSystemClockTime);
+ ipw.println("mLastAutoSystemClockTimeSendNetworkBroadcast="
+ mLastAutoSystemClockTimeSendNetworkBroadcast);
- IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
-
- ipw.println("TimeDetectorStrategyImpl logs:");
- ipw.increaseIndent(); // level 1
ipw.println("Time change log:");
ipw.increaseIndent(); // level 2
@@ -249,6 +251,7 @@
ipw.decreaseIndent(); // level 2
ipw.decreaseIndent(); // level 1
+ ipw.flush();
}
@GuardedBy("this")
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index 32cee2d..0a6c2e7 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -39,6 +39,12 @@
/**
* The interface used by the strategy to interact with the surrounding service.
+ *
+ * <p>Note: Because the system properties-derived value {@link #isAutoTimeDetectionEnabled()}
+ * can be modified independently and from different threads (and processes!). its use is prone
+ * to race conditions. That will be true until the responsibility for setting their values is
+ * moved to {@link TimeDetectorStrategy}. There are similar issues with
+ * {@link #systemClockMillis()} while any process can modify the system clock.
*/
interface Callback {
diff --git a/services/core/java/com/android/server/uri/GrantUri.java b/services/core/java/com/android/server/uri/GrantUri.java
index c694264..1571575 100644
--- a/services/core/java/com/android/server/uri/GrantUri.java
+++ b/services/core/java/com/android/server/uri/GrantUri.java
@@ -67,7 +67,7 @@
return result;
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(GrantUriProto.URI, uri.toString());
proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
diff --git a/services/core/java/com/android/server/uri/NeededUriGrants.java b/services/core/java/com/android/server/uri/NeededUriGrants.java
index 87a2641..0120394 100644
--- a/services/core/java/com/android/server/uri/NeededUriGrants.java
+++ b/services/core/java/com/android/server/uri/NeededUriGrants.java
@@ -34,7 +34,7 @@
this.flags = flags;
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
@@ -42,7 +42,7 @@
final int N = this.size();
for (int i = 0; i < N; i++) {
- this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
+ this.get(i).dumpDebug(proto, NeededUriGrantsProto.GRANTS);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/uri/UriPermissionOwner.java b/services/core/java/com/android/server/uri/UriPermissionOwner.java
index f814dc6..f2c06cd 100644
--- a/services/core/java/com/android/server/uri/UriPermissionOwner.java
+++ b/services/core/java/com/android/server/uri/UriPermissionOwner.java
@@ -141,20 +141,20 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(UriPermissionOwnerProto.OWNER, mOwner.toString());
if (mReadPerms != null) {
synchronized (mReadPerms) {
for (UriPermission p : mReadPerms) {
- p.uri.writeToProto(proto, UriPermissionOwnerProto.READ_PERMS);
+ p.uri.dumpDebug(proto, UriPermissionOwnerProto.READ_PERMS);
}
}
}
if (mWritePerms != null) {
synchronized (mWritePerms) {
for (UriPermission p : mWritePerms) {
- p.uri.writeToProto(proto, UriPermissionOwnerProto.WRITE_PERMS);
+ p.uri.dumpDebug(proto, UriPermissionOwnerProto.WRITE_PERMS);
}
}
}
diff --git a/services/core/java/com/android/server/utils/TimingsTraceAndSlog.java b/services/core/java/com/android/server/utils/TimingsTraceAndSlog.java
index 03c96e9..6bdb5ce 100644
--- a/services/core/java/com/android/server/utils/TimingsTraceAndSlog.java
+++ b/services/core/java/com/android/server/utils/TimingsTraceAndSlog.java
@@ -55,7 +55,16 @@
* Default constructor using {@code system_server} tags.
*/
public TimingsTraceAndSlog() {
- this(SYSTEM_SERVER_TIMING_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ this(SYSTEM_SERVER_TIMING_TAG);
+ }
+
+ /**
+ * Custom constructor using {@code system_server} trace tag.
+ *
+ * @param tag {@code logcat} tag
+ */
+ public TimingsTraceAndSlog(@NonNull String tag) {
+ this(tag, Trace.TRACE_TAG_SYSTEM_SERVER);
}
/**
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index d66aa18..03139d2e 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -104,6 +104,7 @@
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.wm.WindowManagerInternal;
import libcore.io.IoUtils;
@@ -1785,25 +1786,26 @@
@Override
public void onUnlockUser(final int userId) {
- synchronized (mLock) {
- if (mCurrentUserId == userId) {
- if (mWaitingForUnlock) {
- // the desired wallpaper is not direct-boot aware, load it now
- final WallpaperData systemWallpaper =
- getWallpaperSafeLocked(userId, FLAG_SYSTEM);
- switchWallpaper(systemWallpaper, null);
- notifyCallbacksLocked(systemWallpaper);
- }
+ TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG);
+ t.traceBegin("on-unlock-user-" + userId);
+ try {
+ synchronized (mLock) {
+ if (mCurrentUserId == userId) {
+ if (mWaitingForUnlock) {
+ // the desired wallpaper is not direct-boot aware, load it now
+ final WallpaperData systemWallpaper =
+ getWallpaperSafeLocked(userId, FLAG_SYSTEM);
+ switchWallpaper(systemWallpaper, null);
+ notifyCallbacksLocked(systemWallpaper);
+ }
- // Make sure that the SELinux labeling of all the relevant files is correct.
- // This corrects for mislabeling bugs that might have arisen from move-to
- // operations involving the wallpaper files. This isn't timing-critical,
- // so we do it in the background to avoid holding up the user unlock operation.
- if (!mUserRestorecon.get(userId)) {
- mUserRestorecon.put(userId, true);
- Runnable relabeler = new Runnable() {
- @Override
- public void run() {
+ // Make sure that the SELinux labeling of all the relevant files is correct.
+ // This corrects for mislabeling bugs that might have arisen from move-to
+ // operations involving the wallpaper files. This isn't timing-critical,
+ // so we do it in the background to avoid holding up the user unlock operation.
+ if (!mUserRestorecon.get(userId)) {
+ mUserRestorecon.put(userId, true);
+ Runnable relabeler = () -> {
final File wallpaperDir = getWallpaperDir(userId);
for (String filename : sPerUserFiles) {
File f = new File(wallpaperDir, filename);
@@ -1811,11 +1813,13 @@
SELinux.restorecon(f);
}
}
- }
- };
- BackgroundThread.getHandler().post(relabeler);
+ };
+ BackgroundThread.getHandler().post(relabeler);
+ }
}
}
+ } finally {
+ t.traceEnd();
}
}
@@ -1833,31 +1837,37 @@
}
void switchUser(int userId, IRemoteCallback reply) {
- final WallpaperData systemWallpaper;
- final WallpaperData lockWallpaper;
- synchronized (mLock) {
- if (mCurrentUserId == userId) {
- return;
+ TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG);
+ t.traceBegin("switch-user-" + userId);
+ try {
+ final WallpaperData systemWallpaper;
+ final WallpaperData lockWallpaper;
+ synchronized (mLock) {
+ if (mCurrentUserId == userId) {
+ return;
+ }
+ mCurrentUserId = userId;
+ systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
+ final WallpaperData tmpLockWallpaper = mLockWallpaperMap.get(userId);
+ lockWallpaper = tmpLockWallpaper == null ? systemWallpaper : tmpLockWallpaper;
+ // Not started watching yet, in case wallpaper data was loaded for other reasons.
+ if (systemWallpaper.wallpaperObserver == null) {
+ systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
+ systemWallpaper.wallpaperObserver.startWatching();
+ }
+ switchWallpaper(systemWallpaper, reply);
}
- mCurrentUserId = userId;
- systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
- final WallpaperData tmpLockWallpaper = mLockWallpaperMap.get(userId);
- lockWallpaper = tmpLockWallpaper == null ? systemWallpaper : tmpLockWallpaper;
- // Not started watching yet, in case wallpaper data was loaded for other reasons.
- if (systemWallpaper.wallpaperObserver == null) {
- systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
- systemWallpaper.wallpaperObserver.startWatching();
- }
- switchWallpaper(systemWallpaper, reply);
- }
- // Offload color extraction to another thread since switchUser will be called
- // from the main thread.
- FgThread.getHandler().post(() -> {
- notifyWallpaperColorsChanged(systemWallpaper, FLAG_SYSTEM);
- notifyWallpaperColorsChanged(lockWallpaper, FLAG_LOCK);
- notifyWallpaperColorsChanged(mFallbackWallpaper, FLAG_SYSTEM);
- });
+ // Offload color extraction to another thread since switchUser will be called
+ // from the main thread.
+ FgThread.getHandler().post(() -> {
+ notifyWallpaperColorsChanged(systemWallpaper, FLAG_SYSTEM);
+ notifyWallpaperColorsChanged(lockWallpaper, FLAG_LOCK);
+ notifyWallpaperColorsChanged(mFallbackWallpaper, FLAG_SYSTEM);
+ });
+ } finally {
+ t.traceEnd();
+ }
}
void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index db94cf1..84152e8 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -17,8 +17,6 @@
package com.android.server.wm;
import static android.app.ActivityTaskManager.INVALID_STACK_ID;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
@@ -34,7 +32,7 @@
import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
-import static com.android.server.am.ActivityDisplayProto.CONFIGURATION_CONTAINER;
+import static com.android.server.am.ActivityDisplayProto.DISPLAY;
import static com.android.server.am.ActivityDisplayProto.FOCUSED_STACK_ID;
import static com.android.server.am.ActivityDisplayProto.ID;
import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY;
@@ -52,6 +50,7 @@
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.RootActivityContainer.FindTaskResult;
import static com.android.server.wm.RootActivityContainer.TAG_STATES;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
@@ -85,23 +84,19 @@
* Exactly one of these classes per Display in the system. Capable of holding zero or more
* attached {@link ActivityStack}s.
*/
-class ActivityDisplay extends ConfigurationContainer<ActivityStack> {
+class ActivityDisplay extends DisplayContent {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityDisplay" : TAG_ATM;
private static final String TAG_STACK = TAG + POSTFIX_STACK;
static final int POSITION_TOP = Integer.MAX_VALUE;
static final int POSITION_BOTTOM = Integer.MIN_VALUE;
-
/**
* Counter for next free stack ID to use for dynamic activity stacks. Unique across displays.
*/
private static int sNextFreeStackId = 0;
- private ActivityTaskManagerService mService;
private RootActivityContainer mRootActivityContainer;
- // TODO: Remove once unification is complete.
- DisplayContent mDisplayContent;
/** Actual Display this object tracks. */
int mDisplayId;
Display mDisplay;
@@ -111,7 +106,6 @@
* stacks, bottommost behind. Accessed directly by ActivityManager package classes. Any calls
* changing the list should also call {@link #onStackOrderChanged()}.
*/
- private final ArrayList<ActivityStack> mStacks = new ArrayList<>();
private ArrayList<OnStackOrderChangedListener> mStackOrderChangedCallbacks = new ArrayList<>();
/** Array of all UIDs that are present on the display. */
@@ -157,13 +151,6 @@
*/
private ActivityStack mLastFocusedStack;
- // Cached reference to some special stacks we tend to get a lot so we don't need to loop
- // through the list to find them.
- private ActivityStack mHomeStack = null;
- private ActivityStack mRecentsStack = null;
- private ActivityStack mPinnedStack = null;
- private ActivityStack mSplitScreenPrimaryStack = null;
-
// Used in updating the display size
private Point mTmpDisplaySize = new Point();
@@ -173,15 +160,24 @@
private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
ActivityDisplay(RootActivityContainer root, Display display) {
+ super(display, root.mWindowManager);
mRootActivityContainer = root;
- mService = root.mService;
mDisplayId = display.getDisplayId();
mDisplay = display;
- mDisplayContent = mService.mWindowManager.mRoot.createDisplayContent(mDisplay, this);
- mDisplayContent.reconfigureDisplayLocked();
- onRequestedOverrideConfigurationChanged(
- mDisplayContent.getRequestedOverrideConfiguration());
- mService.mWindowManager.mDisplayNotificationController.dispatchDisplayAdded(this);
+
+ if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
+
+ mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this);
+
+ if (mWmService.mDisplayManagerInternal != null) {
+ mWmService.mDisplayManagerInternal
+ .setDisplayInfoOverrideFromWindowManager(mDisplayId, getDisplayInfo());
+ configureDisplayPolicy();
+ }
+
+ reconfigureDisplayLocked();
+ onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration());
+ mWmService.mDisplayNotificationController.dispatchDisplayAdded(this);
}
void onDisplayChanged() {
@@ -190,7 +186,7 @@
if (displayId != DEFAULT_DISPLAY) {
final int displayState = mDisplay.getState();
if (displayState == Display.STATE_OFF && mOffToken == null) {
- mOffToken = mService.acquireSleepToken("Display-off", displayId);
+ mOffToken = mAtmService.acquireSleepToken("Display-off", displayId);
} else if (displayState == Display.STATE_ON && mOffToken != null) {
mOffToken.release();
mOffToken = null;
@@ -199,98 +195,72 @@
mDisplay.getRealSize(mTmpDisplaySize);
setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y);
- if (mDisplayContent != null) {
- mDisplayContent.updateDisplayInfo();
- mService.mWindowManager.requestTraversal();
- }
+ updateDisplayInfo();
+ mWmService.requestTraversal();
}
- // TODO(display-unify): Merge with addChild below.
- void addChild(ActivityStack stack, int position) {
- addChild(stack, position, false /*fromDc*/);
+ void addStack(ActivityStack stack, int position) {
+ setStackOnDisplay(stack, position);
+ positionStackAt(stack, position);
+ mAtmService.updateSleepIfNeededLocked();
}
- void addChild(ActivityStack stack, int position, boolean fromDc) {
- boolean toTop = position == POSITION_TOP;
- if (position == POSITION_BOTTOM) {
- position = 0;
- } else if (toTop) {
- position = getChildCount();
+ void onStackRemoved(ActivityStack stack) {
+ if (DEBUG_STACK) {
+ Slog.v(TAG_STACK, "removeStack: detaching " + stack + " from displayId=" + mDisplayId);
}
- if (DEBUG_STACK) Slog.v(TAG_STACK, "addChild: attaching " + stack
- + " to displayId=" + mDisplayId + " position=" + position);
- addStackReferenceIfNeeded(stack);
- if (!fromDc) {
- mDisplayContent.setStackOnDisplay(stack, position);
- }
- positionChildAt(stack, position);
- mService.updateSleepIfNeededLocked();
- }
-
- // TODO(display-unify): Merge with removeChild below.
- void onChildRemoved(ActivityStack stack) {
- if (!mStacks.remove(stack)) {
- // Stack no longer here!
- return;
- }
-
- if (DEBUG_STACK) Slog.v(TAG_STACK, "removeChild: detaching " + stack
- + " from displayId=" + mDisplayId);
if (mPreferredTopFocusableStack == stack) {
mPreferredTopFocusableStack = null;
}
- removeStackReferenceIfNeeded(stack);
releaseSelfIfNeeded();
- mService.updateSleepIfNeededLocked();
+ mAtmService.updateSleepIfNeededLocked();
onStackOrderChanged(stack);
}
- void removeChild(ActivityStack stack) {
- mDisplayContent.removeStackFromDisplay(stack);
+ void positionStackAtTop(ActivityStack stack, boolean includingParents) {
+ positionStackAtTop(stack, includingParents, null /* updateLastFocusedStackReason */);
}
- void positionChildAtTop(ActivityStack stack, boolean includingParents) {
- positionChildAtTop(stack, includingParents, null /* updateLastFocusedStackReason */);
- }
-
- void positionChildAtTop(ActivityStack stack, boolean includingParents,
+ void positionStackAtTop(ActivityStack stack, boolean includingParents,
String updateLastFocusedStackReason) {
- positionChildAt(stack, getChildCount(), includingParents, updateLastFocusedStackReason);
+ positionStackAt(stack, getStackCount(), includingParents, updateLastFocusedStackReason);
}
- void positionChildAtBottom(ActivityStack stack) {
- positionChildAtBottom(stack, null /* updateLastFocusedStackReason */);
+ void positionStackAtBottom(ActivityStack stack) {
+ positionStackAtBottom(stack, null /* updateLastFocusedStackReason */);
}
- void positionChildAtBottom(ActivityStack stack, String updateLastFocusedStackReason) {
- positionChildAt(stack, 0, false /* includingParents */, updateLastFocusedStackReason);
+ void positionStackAtBottom(ActivityStack stack, String updateLastFocusedStackReason) {
+ positionStackAt(stack, 0, false /* includingParents */, updateLastFocusedStackReason);
}
- private void positionChildAt(ActivityStack stack, int position) {
- positionChildAt(stack, position, false /* includingParents */,
+ private void positionStackAt(ActivityStack stack, int position) {
+ positionStackAt(stack, position, false /* includingParents */,
null /* updateLastFocusedStackReason */);
}
- private void positionChildAt(ActivityStack stack, int position, boolean includingParents,
+ private void positionStackAt(ActivityStack stack, int position, boolean includingParents,
String updateLastFocusedStackReason) {
// TODO: Keep in sync with WindowContainer.positionChildAt(), once we change that to adjust
// the position internally, also update the logic here
final ActivityStack prevFocusedStack = updateLastFocusedStackReason != null
? getFocusedStack() : null;
- final boolean wasContained = mStacks.remove(stack);
- if (mSingleTaskInstance && getChildCount() > 0) {
+ final boolean wasContained = getIndexOf(stack) >= 0;
+ if (mSingleTaskInstance && getStackCount() == 1 && !wasContained) {
throw new IllegalStateException(
- "positionChildAt: Can only have one child on display=" + this);
+ "positionStackAt: Can only have one task on display=" + this);
}
- final int insertPosition = getTopInsertPosition(stack, position);
- mStacks.add(insertPosition, stack);
+
+ // Since positionChildAt() is called during the creation process of pinned stacks,
+ // ActivityStack#getStack() can be null.
+ positionStackAt(position, stack, includingParents);
// The insert position may be adjusted to non-top when there is always-on-top stack. Since
// the original position is preferred to be top, the stack should have higher priority when
// we are looking for top focusable stack. The condition {@code wasContained} restricts the
// preferred stack is set only when moving an existing stack to top instead of adding a new
// stack that may be too early (e.g. in the middle of launching or reparenting).
- if (wasContained && position >= getChildCount() - 1 && stack.isFocusableAndVisible()) {
+ if (wasContained && position >= getStackCount() - 1 && stack.isFocusableAndVisible()) {
mPreferredTopFocusableStack = stack;
} else if (mPreferredTopFocusableStack == stack) {
mPreferredTopFocusableStack = null;
@@ -307,67 +277,14 @@
}
}
- // Since positionChildAt() is called during the creation process of pinned stacks,
- // ActivityStack#getStack() can be null.
- if (mDisplayContent != null) {
- mDisplayContent.positionStackAt(insertPosition, stack, includingParents);
- }
onStackOrderChanged(stack);
}
- private int getTopInsertPosition(ActivityStack stack, int candidatePosition) {
- int position = getChildCount();
- if (stack.inPinnedWindowingMode()) {
- // Stack in pinned windowing mode is z-ordered on-top of all other stacks so okay to
- // just return the candidate position.
- return Math.min(position, candidatePosition);
- }
- while (position > 0) {
- final ActivityStack targetStack = getChildAt(position - 1);
- if (!targetStack.isAlwaysOnTop()) {
- // We reached a stack that isn't always-on-top.
- break;
- }
- if (stack.isAlwaysOnTop() && !targetStack.inPinnedWindowingMode()) {
- // Always on-top non-pinned windowing mode stacks can go anywhere below pinned stack.
- break;
- }
- position--;
- }
- return Math.min(position, candidatePosition);
- }
-
- <T extends ActivityStack> T getStack(int stackId) {
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = getChildAt(i);
+ ActivityStack getStack(int stackId) {
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack stack = getStackAt(i);
if (stack.mStackId == stackId) {
- return (T) stack;
- }
- }
- return null;
- }
-
- /**
- * @return the topmost stack on the display that is compatible with the input windowing mode and
- * activity type. {@code null} means no compatible stack on the display.
- * @see ConfigurationContainer#isCompatible(int, int)
- */
- <T extends ActivityStack> T getStack(int windowingMode, int activityType) {
- if (activityType == ACTIVITY_TYPE_HOME) {
- return (T) mHomeStack;
- } else if (activityType == ACTIVITY_TYPE_RECENTS) {
- return (T) mRecentsStack;
- }
- if (windowingMode == WINDOWING_MODE_PINNED) {
- return (T) mPinnedStack;
- } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
- return (T) mSplitScreenPrimaryStack;
- }
-
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = getChildAt(i);
- if (stack.isCompatible(windowingMode, activityType)) {
- return (T) stack;
+ return stack;
}
}
return null;
@@ -388,10 +305,10 @@
* @see #getStack(int, int)
* @see #createStack(int, int, boolean)
*/
- <T extends ActivityStack> T getOrCreateStack(int windowingMode, int activityType,
+ ActivityStack getOrCreateStack(int windowingMode, int activityType,
boolean onTop) {
if (!alwaysCreateStack(windowingMode, activityType)) {
- T stack = getStack(windowingMode, activityType);
+ ActivityStack stack = getStack(windowingMode, activityType);
if (stack != null) {
return stack;
}
@@ -404,7 +321,7 @@
* if a compatible stack doesn't exist.
* @see #getOrCreateStack(int, int, boolean)
*/
- <T extends ActivityStack> T getOrCreateStack(@Nullable ActivityRecord r,
+ ActivityStack getOrCreateStack(@Nullable ActivityRecord r,
@Nullable ActivityOptions options, @Nullable Task candidateTask, int activityType,
boolean onTop) {
// First preference is the windowing mode in the activity options if set.
@@ -433,9 +350,9 @@
* @param onTop If true the stack will be created at the top of the display, else at the bottom.
* @return The newly created stack.
*/
- <T extends ActivityStack> T createStack(int windowingMode, int activityType, boolean onTop) {
+ ActivityStack createStack(int windowingMode, int activityType, boolean onTop) {
- if (mSingleTaskInstance && getChildCount() > 0) {
+ if (mSingleTaskInstance && getStackCount() > 0) {
// Create stack on default display instead since this display can only contain 1 stack.
// TODO: Kinda a hack, but better that having the decision at each call point. Hoping
// this goes away once ActivityView is no longer using virtual displays.
@@ -452,17 +369,17 @@
if (activityType != ACTIVITY_TYPE_STANDARD) {
// For now there can be only one stack of a particular non-standard activity type on a
// display. So, get that ignoring whatever windowing mode it is currently in.
- T stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
+ ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
if (stack != null) {
throw new IllegalArgumentException("Stack=" + stack + " of activityType="
+ activityType + " already on display=" + this + ". Can't have multiple.");
}
}
- if (!isWindowingModeSupported(windowingMode, mService.mSupportsMultiWindow,
- mService.mSupportsSplitScreenMultiWindow,
- mService.mSupportsFreeformWindowManagement, mService.mSupportsPictureInPicture,
- activityType)) {
+ if (!isWindowingModeSupported(windowingMode, mAtmService.mSupportsMultiWindow,
+ mAtmService.mSupportsSplitScreenMultiWindow,
+ mAtmService.mSupportsFreeformWindowManagement,
+ mAtmService.mSupportsPictureInPicture, activityType)) {
throw new IllegalArgumentException("Can't create stack for unsupported windowingMode="
+ windowingMode);
}
@@ -472,13 +389,13 @@
}
@VisibleForTesting
- <T extends ActivityStack> T createStackUnchecked(int windowingMode, int activityType,
+ ActivityStack createStackUnchecked(int windowingMode, int activityType,
int stackId, boolean onTop) {
if (windowingMode == WINDOWING_MODE_PINNED && activityType != ACTIVITY_TYPE_STANDARD) {
throw new IllegalArgumentException("Stack with windowing mode cannot with non standard "
+ "activity type.");
}
- return (T) new ActivityStack(this, stackId,
+ return new ActivityStack(this, stackId,
mRootActivityContainer.mStackSupervisor, windowingMode, activityType, onTop);
}
@@ -491,8 +408,8 @@
return mPreferredTopFocusableStack;
}
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = getChildAt(i);
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack stack = getStackAt(i);
if (stack.isFocusableAndVisible()) {
return stack;
}
@@ -506,8 +423,8 @@
? currentFocus.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
ActivityStack candidate = null;
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = getChildAt(i);
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack stack = getStackAt(i);
if (ignoreCurrent && stack == currentFocus) {
continue;
}
@@ -562,8 +479,8 @@
}
boolean allResumedActivitiesComplete() {
- for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityRecord r = getChildAt(stackNdx).getResumedActivity();
+ for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityRecord r = getStackAt(stackNdx).getResumedActivity();
if (r != null && !r.isState(RESUMED)) {
return false;
}
@@ -589,8 +506,8 @@
*/
boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming) {
boolean someActivityPaused = false;
- for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = getChildAt(stackNdx);
+ for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = getStackAt(stackNdx);
final ActivityRecord resumedActivity = stack.getResumedActivity();
if (resumedActivity != null
&& (stack.getVisibility(resuming) != STACK_VISIBILITY_VISIBLE
@@ -610,8 +527,8 @@
void findTaskLocked(final ActivityRecord r, final boolean isPreferredDisplay,
FindTaskResult result) {
mTmpFindTaskResult.clear();
- for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = getChildAt(stackNdx);
+ for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = getStackAt(stackNdx);
if (!r.hasCompatibleActivityType(stack)) {
if (DEBUG_TASKS) {
Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) " + stack);
@@ -654,8 +571,8 @@
final ArrayList<ActivityStack> stacks = new ArrayList<>();
for (int j = windowingModes.length - 1 ; j >= 0; --j) {
final int windowingMode = windowingModes[j];
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = getChildAt(i);
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack stack = getStackAt(i);
if (!stack.isActivityTypeStandardOrUndefined()) {
continue;
}
@@ -682,8 +599,8 @@
final ArrayList<ActivityStack> stacks = new ArrayList<>();
for (int j = activityTypes.length - 1 ; j >= 0; --j) {
final int activityType = activityTypes[j];
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = getChildAt(i);
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack stack = getStackAt(i);
if (stack.getActivityType() == activityType) {
stacks.add(stack);
}
@@ -695,67 +612,12 @@
}
}
- void onStackWindowingModeChanged(ActivityStack stack) {
- removeStackReferenceIfNeeded(stack);
- addStackReferenceIfNeeded(stack);
- }
-
- private void addStackReferenceIfNeeded(ActivityStack stack) {
- final int activityType = stack.getActivityType();
- final int windowingMode = stack.getWindowingMode();
-
- if (activityType == ACTIVITY_TYPE_HOME) {
- if (mHomeStack != null && mHomeStack != stack) {
- throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack="
- + mHomeStack + " already exist on display=" + this + " stack=" + stack);
- }
- mHomeStack = stack;
- } else if (activityType == ACTIVITY_TYPE_RECENTS) {
- if (mRecentsStack != null && mRecentsStack != stack) {
- throw new IllegalArgumentException("addStackReferenceIfNeeded: recents stack="
- + mRecentsStack + " already exist on display=" + this + " stack=" + stack);
- }
- mRecentsStack = stack;
- }
- if (windowingMode == WINDOWING_MODE_PINNED) {
- if (mPinnedStack != null && mPinnedStack != stack) {
- throw new IllegalArgumentException("addStackReferenceIfNeeded: pinned stack="
- + mPinnedStack + " already exist on display=" + this
- + " stack=" + stack);
- }
- mPinnedStack = stack;
- } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
- if (mSplitScreenPrimaryStack != null && mSplitScreenPrimaryStack != stack) {
- throw new IllegalArgumentException("addStackReferenceIfNeeded:"
- + " split-screen-primary" + " stack=" + mSplitScreenPrimaryStack
- + " already exist on display=" + this + " stack=" + stack);
- }
- mSplitScreenPrimaryStack = stack;
- onSplitScreenModeActivated();
- }
- }
-
- private void removeStackReferenceIfNeeded(ActivityStack stack) {
- if (stack == mHomeStack) {
- mHomeStack = null;
- } else if (stack == mRecentsStack) {
- mRecentsStack = null;
- } else if (stack == mPinnedStack) {
- mPinnedStack = null;
- } else if (stack == mSplitScreenPrimaryStack) {
- mSplitScreenPrimaryStack = null;
- // Inform the reset of the system that split-screen mode was dismissed so things like
- // resizing all the other stacks can take place.
- onSplitScreenModeDismissed();
- }
- }
-
- private void onSplitScreenModeDismissed() {
- mService.deferWindowLayout();
+ void onSplitScreenModeDismissed() {
+ mAtmService.deferWindowLayout();
try {
// Adjust the windowing mode of any stack in secondary split-screen to fullscreen.
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack otherStack = getChildAt(i);
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack otherStack = getStackAt(i);
if (!otherStack.inSplitScreenSecondaryWindowingMode()) {
continue;
}
@@ -766,26 +628,28 @@
} finally {
final ActivityStack topFullscreenStack =
getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN);
- if (topFullscreenStack != null && mHomeStack != null && !isTopStack(mHomeStack)) {
+ final ActivityStack homeStack = getHomeStack();
+ if (topFullscreenStack != null && homeStack != null && !isTopStack(homeStack)) {
// Whenever split-screen is dismissed we want the home stack directly behind the
// current top fullscreen stack so it shows up when the top stack is finished.
// TODO: Would be better to use ActivityDisplay.positionChildAt() for this, however
// ActivityDisplay doesn't have a direct controller to WM side yet. We can switch
// once we have that.
- mHomeStack.moveToFront("onSplitScreenModeDismissed");
+ homeStack.moveToFront("onSplitScreenModeDismissed");
topFullscreenStack.moveToFront("onSplitScreenModeDismissed");
}
- mService.continueWindowLayout();
+ mAtmService.continueWindowLayout();
}
}
- private void onSplitScreenModeActivated() {
- mService.deferWindowLayout();
+ void onSplitScreenModeActivated() {
+ mAtmService.deferWindowLayout();
try {
// Adjust the windowing mode of any affected by split-screen to split-screen secondary.
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack otherStack = getChildAt(i);
- if (otherStack == mSplitScreenPrimaryStack
+ final ActivityStack splitScreenPrimaryStack = getSplitScreenPrimaryStack();
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack otherStack = getStackAt(i);
+ if (otherStack == splitScreenPrimaryStack
|| !otherStack.affectedBySplitScreenResize()) {
continue;
}
@@ -795,7 +659,7 @@
false /* creating */);
}
} finally {
- mService.continueWindowLayout();
+ mAtmService.continueWindowLayout();
}
}
@@ -890,10 +754,10 @@
int validateWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task,
int activityType) {
// Make sure the windowing mode we are trying to use makes sense for what is supported.
- boolean supportsMultiWindow = mService.mSupportsMultiWindow;
- boolean supportsSplitScreen = mService.mSupportsSplitScreenMultiWindow;
- boolean supportsFreeform = mService.mSupportsFreeformWindowManagement;
- boolean supportsPip = mService.mSupportsPictureInPicture;
+ boolean supportsMultiWindow = mAtmService.mSupportsMultiWindow;
+ boolean supportsSplitScreen = mAtmService.mSupportsSplitScreenMultiWindow;
+ boolean supportsFreeform = mAtmService.mSupportsFreeformWindowManagement;
+ boolean supportsPip = mAtmService.mSupportsPictureInPicture;
if (supportsMultiWindow) {
if (task != null) {
supportsMultiWindow = task.isResizeable();
@@ -927,21 +791,13 @@
return WINDOWING_MODE_UNDEFINED;
}
- /**
- * Get the topmost stack on the display. It may be different from focused stack, because
- * some stacks are not focusable (e.g. PiP).
- */
- ActivityStack getTopStack() {
- return mStacks.isEmpty() ? null : getChildAt(getChildCount() - 1);
- }
-
boolean isTopStack(ActivityStack stack) {
return stack == getTopStack();
}
boolean isTopNotPinnedStack(ActivityStack stack) {
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack current = getChildAt(i);
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack current = getStackAt(i);
if (!current.inPinnedWindowingMode()) {
return current == stack;
}
@@ -950,8 +806,8 @@
}
ActivityStack getTopStackInWindowingMode(int windowingMode) {
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack current = getChildAt(i);
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack current = getStackAt(i);
if (windowingMode == current.getWindowingMode()) {
return current;
}
@@ -981,8 +837,8 @@
// Look in other focusable stacks.
if (topRunning == null) {
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = getChildAt(i);
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack stack = getStackAt(i);
// Only consider focusable stacks other than the current focused one.
if (stack == focusedStack || !stack.isFocusable()) {
continue;
@@ -1005,22 +861,18 @@
return topRunning;
}
- int getIndexOf(ActivityStack stack) {
- return mStacks.indexOf(stack);
- }
-
boolean updateDisplayOverrideConfigurationLocked() {
Configuration values = new Configuration();
- mDisplayContent.computeScreenConfiguration(values);
+ computeScreenConfiguration(values);
- mService.mH.sendMessage(PooledLambda.obtainMessage(
- ActivityManagerInternal::updateOomLevelsForDisplay, mService.mAmInternal,
+ mAtmService.mH.sendMessage(PooledLambda.obtainMessage(
+ ActivityManagerInternal::updateOomLevelsForDisplay, mAtmService.mAmInternal,
mDisplayId));
Settings.System.clearConfiguration(values);
updateDisplayOverrideConfigurationLocked(values, null /* starting */,
- false /* deferResume */, mService.mTmpUpdateConfigurationResult);
- return mService.mTmpUpdateConfigurationResult.changes != 0;
+ false /* deferResume */, mAtmService.mTmpUpdateConfigurationResult);
+ return mAtmService.mTmpUpdateConfigurationResult.changes != 0;
}
/**
@@ -1034,14 +886,14 @@
int changes = 0;
boolean kept = true;
- mService.deferWindowLayout();
+ mAtmService.deferWindowLayout();
try {
if (values != null) {
if (mDisplayId == DEFAULT_DISPLAY) {
// Override configuration of the default display duplicates global config, so
// we're calling global config update instead for default display. It will also
// apply the correct override config.
- changes = mService.updateGlobalConfigurationLocked(values,
+ changes = mAtmService.updateGlobalConfigurationLocked(values,
false /* initLocale */, false /* persistent */,
UserHandle.USER_NULL /* userId */, deferResume);
} else {
@@ -1049,9 +901,9 @@
}
}
- kept = mService.ensureConfigAndVisibilityAfterUpdate(starting, changes);
+ kept = mAtmService.ensureConfigAndVisibilityAfterUpdate(starting, changes);
} finally {
- mService.continueWindowLayout();
+ mAtmService.continueWindowLayout();
}
if (result != null) {
@@ -1071,17 +923,17 @@
final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
if (isDensityChange && mDisplayId == DEFAULT_DISPLAY) {
- mService.mAppWarnings.onDensityChanged();
+ mAtmService.mAppWarnings.onDensityChanged();
// Post message to start process to avoid possible deadlock of calling into AMS with
// the ATMS lock held.
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::killAllBackgroundProcessesExcept,
- mService.mAmInternal, N,
+ mAtmService.mAmInternal, N,
ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
- mService.mH.sendMessage(msg);
+ mAtmService.mH.sendMessage(msg);
}
- mService.mWindowManager.mDisplayNotificationController.dispatchDisplayChanged(
+ mWmService.mDisplayNotificationController.dispatchDisplayChanged(
this, getConfiguration());
}
return changes;
@@ -1092,43 +944,29 @@
final int currRotation =
getRequestedOverrideConfiguration().windowConfiguration.getRotation();
if (currRotation != ROTATION_UNDEFINED
- && currRotation != overrideConfiguration.windowConfiguration.getRotation()
- && mDisplayContent != null) {
- mDisplayContent.applyRotationLocked(currRotation,
+ && currRotation != overrideConfiguration.windowConfiguration.getRotation()) {
+ applyRotationLocked(currRotation,
overrideConfiguration.windowConfiguration.getRotation());
}
super.onRequestedOverrideConfigurationChanged(overrideConfiguration);
- if (mDisplayContent != null) {
- mService.mWindowManager.setNewDisplayOverrideConfiguration(
- overrideConfiguration, mDisplayContent);
- }
- mService.addWindowLayoutReasons(
+ mWmService.setNewDisplayOverrideConfiguration(overrideConfiguration, this);
+ mAtmService.addWindowLayoutReasons(
ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED);
}
@Override
public void onConfigurationChanged(Configuration newParentConfig) {
// update resources before cascade so that docked/pinned stacks use the correct info
- if (mDisplayContent != null) {
- mDisplayContent.preOnConfigurationChanged();
- }
+ preOnConfigurationChanged();
super.onConfigurationChanged(newParentConfig);
}
void onLockTaskPackagesUpdated() {
- for (int i = getChildCount() - 1; i >= 0; --i) {
- getChildAt(i).onLockTaskPackagesUpdated();
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ getStackAt(i).onLockTaskPackagesUpdated();
}
}
- /** We are in the process of exiting split-screen mode. */
- void onExitingSplitScreenMode() {
- // Remove reference to the primary-split-screen stack so it no longer has any effect on the
- // display. For example, we want to be able to create fullscreen stack for standard activity
- // types when exiting split-screen mode.
- mSplitScreenPrimaryStack = null;
- }
-
/** Checks whether the given activity is in size compatibility mode and notifies the change. */
void handleActivitySizeCompatModeIfNeeded(ActivityRecord r) {
if (!r.isState(RESUMED) || r.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
@@ -1137,7 +975,7 @@
}
if (!r.inSizeCompatMode()) {
if (mLastCompatModeActivity != null) {
- mService.getTaskChangeNotificationController()
+ mAtmService.getTaskChangeNotificationController()
.notifySizeCompatModeActivityChanged(mDisplayId, null /* activityToken */);
}
mLastCompatModeActivity = null;
@@ -1147,44 +985,13 @@
return;
}
mLastCompatModeActivity = r;
- mService.getTaskChangeNotificationController()
+ mAtmService.getTaskChangeNotificationController()
.notifySizeCompatModeActivityChanged(mDisplayId, r.appToken);
}
- ActivityStack getSplitScreenPrimaryStack() {
- return mSplitScreenPrimaryStack;
- }
-
- boolean hasSplitScreenPrimaryStack() {
- return mSplitScreenPrimaryStack != null;
- }
-
- ActivityStack getPinnedStack() {
- return mPinnedStack;
- }
-
- boolean hasPinnedStack() {
- return mPinnedStack != null;
- }
-
@Override
public String toString() {
- return "ActivityDisplay={" + mDisplayId + " numStacks=" + getChildCount() + "}";
- }
-
- @Override
- protected int getChildCount() {
- return mStacks.size();
- }
-
- @Override
- protected ActivityStack getChildAt(int index) {
- return mStacks.get(index);
- }
-
- @Override
- protected ConfigurationContainer getParent() {
- return mRootActivityContainer;
+ return "ActivityDisplay={" + mDisplayId + " numStacks=" + getStackCount() + "}";
}
boolean isPrivate() {
@@ -1227,10 +1034,10 @@
final ActivityDisplay toDisplay = mRootActivityContainer.getDefaultDisplay();
mRootActivityContainer.mStackSupervisor.beginDeferResume();
try {
- int numStacks = getChildCount();
+ int numStacks = getStackCount();
// Keep the order from bottom to top.
for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) {
- final ActivityStack stack = getChildAt(stackNdx);
+ final ActivityStack stack = getStackAt(stackNdx);
// Always finish non-standard type stacks.
if (destroyContentOnRemoval || !stack.isActivityTypeStandardOrUndefined()) {
stack.finishAllActivitiesImmediately();
@@ -1241,14 +1048,14 @@
final int windowingMode = toDisplay.hasSplitScreenPrimaryStack()
? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
: WINDOWING_MODE_UNDEFINED;
- stack.reparent(toDisplay.mDisplayContent, true /* onTop */);
+ stack.reparent(toDisplay, true /* onTop */);
stack.setWindowingMode(windowingMode);
lastReparentedStack = stack;
}
// Stacks may be removed from this display. Ensure each stack will be processed and
// the loop will end.
- stackNdx -= numStacks - getChildCount();
- numStacks = getChildCount();
+ stackNdx -= numStacks - getStackCount();
+ numStacks = getStackCount();
}
} finally {
mRootActivityContainer.mStackSupervisor.endDeferResume();
@@ -1265,24 +1072,23 @@
if (!mAllSleepTokens.isEmpty()) {
mRootActivityContainer.mSleepTokens.removeAll(mAllSleepTokens);
mAllSleepTokens.clear();
- mService.updateSleepIfNeededLocked();
+ mAtmService.updateSleepIfNeededLocked();
}
}
private void releaseSelfIfNeeded() {
- if (!mRemoved || mDisplayContent == null) {
+ if (!mRemoved) {
return;
}
- final ActivityStack stack = getChildCount() == 1 ? getChildAt(0) : null;
+ final ActivityStack stack = getStackCount() == 1 ? getStackAt(0) : null;
if (stack != null && stack.isActivityTypeHome() && stack.getAllTasks().isEmpty()) {
// Release this display if an empty home stack is the only thing left.
// Since it is the last stack, this display will be released along with the stack
// removal.
stack.removeIfPossible();
- } else if (mStacks.isEmpty()) {
- mDisplayContent.removeIfPossible();
- mDisplayContent = null;
+ } else if (getTopStack() == null) {
+ removeIfPossible();
mRootActivityContainer.removeChild(this);
mRootActivityContainer.mStackSupervisor
.getKeyguardController().onDisplayRemoved(mDisplayId);
@@ -1302,14 +1108,6 @@
private static void addActivityUid(ActivityRecord r, IntArray uids) {
uids.add(r.getUid());
}
- /**
- * Checks if system decorations should be shown on this display.
- *
- * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
- */
- boolean supportsSystemDecorations() {
- return mDisplayContent.supportsSystemDecorations();
- }
@VisibleForTesting
boolean shouldDestroyContentOnRemove() {
@@ -1317,14 +1115,11 @@
}
boolean shouldSleep() {
- return (mStacks.isEmpty() || !mAllSleepTokens.isEmpty())
- && (mService.mRunningVoice == null);
+ return (getStackCount() == 0 || !mAllSleepTokens.isEmpty())
+ && (mAtmService.mRunningVoice == null);
}
void setFocusedApp(ActivityRecord r, boolean moveFocusNow) {
- if (mDisplayContent == null) {
- return;
- }
final ActivityRecord newFocus;
final IBinder token = r.appToken;
if (token == null) {
@@ -1332,7 +1127,7 @@
mDisplayId);
newFocus = null;
} else {
- newFocus = mService.mWindowManager.mRoot.getActivityRecord(token);
+ newFocus = mWmService.mRoot.getActivityRecord(token);
if (newFocus == null) {
Slog.w(TAG_WM, "Attempted to set focus to non-existing app token: " + token
+ ", displayId=" + mDisplayId);
@@ -1342,9 +1137,9 @@
moveFocusNow, mDisplayId);
}
- final boolean changed = mDisplayContent.setFocusedApp(newFocus);
+ final boolean changed = setFocusedApp(newFocus);
if (moveFocusNow && changed) {
- mService.mWindowManager.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
+ mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
true /*updateInputWindows*/);
}
}
@@ -1354,8 +1149,8 @@
* already top-most.
*/
ActivityStack getStackAbove(ActivityStack stack) {
- final int stackIndex = mStacks.indexOf(stack) + 1;
- return (stackIndex < getChildCount()) ? getChildAt(stackIndex) : null;
+ final int stackIndex = getIndexOf(stack) + 1;
+ return (stackIndex < getStackCount()) ? getStackAt(stackIndex) : null;
}
/**
@@ -1369,12 +1164,12 @@
}
// Move the stack to the bottom to not affect the following visibility checks
- positionChildAtBottom(stack);
+ positionStackAtBottom(stack);
// Find the next position where the stack should be placed
- final int numStacks = getChildCount();
+ final int numStacks = getStackCount();
for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) {
- final ActivityStack s = getChildAt(stackNdx);
+ final ActivityStack s = getStackAt(stackNdx);
if (s == stack) {
continue;
}
@@ -1383,7 +1178,7 @@
winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
if (s.shouldBeVisible(null) && isValidWindowingMode) {
// Move the provided stack to behind this stack
- positionChildAt(stack, Math.max(0, stackNdx - 1));
+ positionStackAt(stack, Math.max(0, stackNdx - 1));
break;
}
}
@@ -1403,25 +1198,26 @@
// list, so we need to adjust the insertion index to account for the removed index
// TODO: Remove this logic when WindowContainer.positionChildAt() is updated to adjust the
// position internally
- final int stackIndex = mStacks.indexOf(stack);
- final int behindStackIndex = mStacks.indexOf(behindStack);
+ final int stackIndex = getIndexOf(stack);
+ final int behindStackIndex = getIndexOf(behindStack);
final int insertIndex = stackIndex <= behindStackIndex
? behindStackIndex - 1 : behindStackIndex;
- positionChildAt(stack, Math.max(0, insertIndex));
+ positionStackAt(stack, Math.max(0, insertIndex));
}
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
- for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = getChildAt(stackNdx);
+ for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = getStackAt(stackNdx);
stack.ensureActivitiesVisible(starting, configChanges, preserveWindows,
notifyClients);
}
}
void moveHomeStackToFront(String reason) {
- if (mHomeStack != null) {
- mHomeStack.moveToFront(reason);
+ final ActivityStack homeStack = getHomeStack();
+ if (homeStack != null) {
+ homeStack.moveToFront(reason);
}
}
@@ -1439,25 +1235,21 @@
}
@Nullable
- ActivityStack getHomeStack() {
- return mHomeStack;
- }
-
- @Nullable
ActivityRecord getHomeActivity() {
return getHomeActivityForUser(mRootActivityContainer.mCurrentUser);
}
@Nullable
ActivityRecord getHomeActivityForUser(int userId) {
- if (mHomeStack == null) {
+ final ActivityStack homeStack = getHomeStack();
+ if (homeStack == null) {
return null;
}
final PooledPredicate p = PooledLambda.obtainPredicate(
ActivityDisplay::isHomeActivityForUser, PooledLambda.__(ActivityRecord.class),
userId);
- final ActivityRecord r = mHomeStack.getActivity(p);
+ final ActivityRecord r = homeStack.getActivity(p);
p.recycle();
return r;
}
@@ -1502,32 +1294,14 @@
}
}
- /**
- * See {@link DisplayContent#deferUpdateImeTarget()}
- */
- public void deferUpdateImeTarget() {
- if (mDisplayContent != null) {
- mDisplayContent.deferUpdateImeTarget();
- }
- }
-
- /**
- * See {@link DisplayContent#deferUpdateImeTarget()}
- */
- public void continueUpdateImeTarget() {
- if (mDisplayContent != null) {
- mDisplayContent.continueUpdateImeTarget();
- }
- }
-
void setDisplayToSingleTaskInstance() {
- final int childCount = getChildCount();
+ final int childCount = getStackCount();
if (childCount > 1) {
throw new IllegalArgumentException("Display already has multiple stacks. display="
+ this);
}
if (childCount > 0) {
- final ActivityStack stack = getChildAt(0);
+ final ActivityStack stack = getStackAt(0);
if (stack.getChildCount() > 1) {
throw new IllegalArgumentException("Display stack already has multiple tasks."
+ " display=" + this + " stack=" + stack);
@@ -1544,8 +1318,8 @@
@VisibleForTesting
void removeAllTasks() {
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = getChildAt(i);
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack stack = getStackAt(i);
final ArrayList<Task> tasks = stack.getAllTasks();
for (int j = tasks.size() - 1; j >= 0; --j) {
stack.removeChild(tasks.get(j), "removeAllTasks");
@@ -1554,20 +1328,24 @@
}
public void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + getChildCount()
+ pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + getStackCount()
+ (mSingleTaskInstance ? " mSingleTaskInstance" : ""));
final String myPrefix = prefix + " ";
- if (mHomeStack != null) {
- pw.println(myPrefix + "mHomeStack=" + mHomeStack);
+ ActivityStack stack = getHomeStack();
+ if (stack != null) {
+ pw.println(myPrefix + "mHomeStack=" + stack);
}
- if (mRecentsStack != null) {
- pw.println(myPrefix + "mRecentsStack=" + mRecentsStack);
+ stack = getRecentsStack();
+ if (stack != null) {
+ pw.println(myPrefix + "mRecentsStack=" + stack);
}
- if (mPinnedStack != null) {
- pw.println(myPrefix + "mPinnedStack=" + mPinnedStack);
+ stack = getPinnedStack();
+ if (stack != null) {
+ pw.println(myPrefix + "mPinnedStack=" + stack);
}
- if (mSplitScreenPrimaryStack != null) {
- pw.println(myPrefix + "mSplitScreenPrimaryStack=" + mSplitScreenPrimaryStack);
+ stack = getSplitScreenPrimaryStack();
+ if (stack != null) {
+ pw.println(myPrefix + "mSplitScreenPrimaryStack=" + stack);
}
if (mPreferredTopFocusableStack != null) {
pw.println(myPrefix + "mPreferredTopFocusableStack=" + mPreferredTopFocusableStack);
@@ -1578,18 +1356,18 @@
}
public void dumpStacks(PrintWriter pw) {
- for (int i = getChildCount() - 1; i >= 0; --i) {
- pw.print(getChildAt(i).mStackId);
+ for (int i = getStackCount() - 1; i >= 0; --i) {
+ pw.print(getStackAt(i).mStackId);
if (i > 0) {
pw.print(",");
}
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
final long token = proto.start(fieldId);
- super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
+ dumpDebugInner(proto, DISPLAY, logLevel);
proto.write(ID, mDisplayId);
proto.write(SINGLE_TASK_INSTANCE, mSingleTaskInstance);
final ActivityStack focusedStack = getFocusedStack();
@@ -1602,9 +1380,9 @@
} else {
proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
}
- for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = getChildAt(stackNdx);
- stack.writeToProto(proto, STACKS, logLevel);
+ for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = getStackAt(stackNdx);
+ stack.dumpDebug(proto, STACKS, logLevel);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index de51d4b..20d1d1c 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -1182,7 +1182,7 @@
final ProtoOutputStream protoOutputStream =
new ProtoOutputStream(LAUNCH_OBSERVER_ACTIVITY_RECORD_PROTO_CHUNK_SIZE);
// Write this data out as the top-most ActivityRecordProto (i.e. it is not a sub-object).
- record.writeToProto(protoOutputStream);
+ record.dumpDebug(protoOutputStream);
final byte[] bytes = protoOutputStream.getBytes();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 963e090..5d79605 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2237,7 +2237,7 @@
}
}
return (getWindowConfiguration().canReceiveKeys() || isAlwaysFocusable())
- && getParent() != null;
+ && getDisplay() != null;
}
/** Move activity with its stack to front and make the stack focused. */
@@ -2256,7 +2256,8 @@
return false;
}
- if (mRootActivityContainer.getTopResumedActivity() == this) {
+ if (mRootActivityContainer.getTopResumedActivity() == this
+ && getDisplayContent().mFocusedApp == this) {
if (DEBUG_FOCUS) {
Slog.d(TAG_FOCUS, "moveActivityStackToFront: already on top, activity=" + this);
}
@@ -2420,7 +2421,7 @@
final ActivityDisplay display = stack.getDisplay();
next = display.topRunningActivity();
if (next != null) {
- display.positionChildAtTop(next.getActivityStack(),
+ display.positionStackAtTop(next.getActivityStack(),
false /* includingParents */, "finish-display-top");
}
}
@@ -5688,8 +5689,6 @@
@Override
boolean isWaitingForTransitionStart() {
final DisplayContent dc = getDisplayContent();
- // TODO(display-unify): Test for null can be removed once unification is done.
- if (dc == null) return false;
return dc.mAppTransition.isTransitionSet()
&& (dc.mOpeningApps.contains(this)
|| dc.mClosingApps.contains(this)
@@ -7314,8 +7313,8 @@
* Write all fields to an {@code ActivityRecordProto}. This assumes the
* {@code ActivityRecordProto} is the outer-most proto data.
*/
- void writeToProto(ProtoOutputStream proto) {
- writeToProto(proto, APP_WINDOW_TOKEN, WindowTraceLogLevel.ALL);
+ void dumpDebug(ProtoOutputStream proto) {
+ dumpDebug(proto, APP_WINDOW_TOKEN, WindowTraceLogLevel.ALL);
writeIdentifierToProto(proto, IDENTIFIER);
proto.write(STATE, mState.toString());
proto.write(VISIBLE_REQUESTED, mVisibleRequested);
@@ -7327,9 +7326,9 @@
proto.write(VISIBLE, mVisible);
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- writeToProto(proto);
+ dumpDebug(proto);
proto.end(token);
}
@@ -7337,7 +7336,7 @@
* Copied from old AppWindowToken.
*/
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
// Critical log level logs only visible elements to mitigate performance overheard
if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
@@ -7346,12 +7345,12 @@
final long token = proto.start(fieldId);
writeNameToProto(proto, NAME);
- super.writeToProto(proto, WINDOW_TOKEN, logLevel);
+ super.dumpDebug(proto, WINDOW_TOKEN, logLevel);
proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
proto.write(IS_ANIMATING, isAnimating());
if (mThumbnail != null){
- mThumbnail.writeToProto(proto, THUMBNAIL);
+ mThumbnail.dumpDebug(proto, THUMBNAIL);
}
proto.write(FILLS_PARENT, mOccludesParent);
proto.write(APP_STOPPED, mAppStopped);
@@ -7372,7 +7371,7 @@
proto.write(VISIBLE_SET_FROM_TRANSFERRED_STARTING_WINDOW,
mVisibleSetFromTransferredStartingWindow);
for (Rect bounds : mFrozenBounds) {
- bounds.writeToProto(proto, FROZEN_BOUNDS);
+ bounds.dumpDebug(proto, FROZEN_BOUNDS);
}
proto.write(com.android.server.wm.AppWindowTokenProto.VISIBLE, mVisible);
proto.end(token);
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index bb3126b..cc45671 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -750,7 +750,7 @@
// stacks on a wrong display.
mDisplayId = display.mDisplayId;
setActivityType(activityType);
- display.addChild(this, onTop ? POSITION_TOP : POSITION_BOTTOM);
+ display.addStack(this, onTop ? POSITION_TOP : POSITION_BOTTOM);
setWindowingMode(windowingMode, false /* animate */, false /* showRecents */,
false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */,
true /* creating */);
@@ -879,7 +879,6 @@
newBounds /* outStackBounds */, mTmpRect2 /* outTempTaskBounds */);
hasNewOverrideBounds = true;
}
- display.onStackWindowingModeChanged(this);
}
if (hasNewOverrideBounds) {
if (inSplitScreenPrimaryWindowingMode()) {
@@ -896,7 +895,7 @@
// Since always on top is only on when the stack is freeform or pinned, the state
// can be toggled when the windowing mode changes. We must make sure the stack is
// placed properly when always on top state changes.
- display.positionChildAtTop(this, false /* includingParents */);
+ display.positionStackAtTop(this, false /* includingParents */);
}
}
@@ -1337,7 +1336,7 @@
}
final boolean movingTask = task != null;
- display.positionChildAtTop(this, !movingTask /* includingParents */, reason);
+ display.positionStackAtTop(this, !movingTask /* includingParents */, reason);
if (movingTask) {
// This also moves the entire hierarchy branch to top, including parents
positionChildAtTop(task);
@@ -1353,7 +1352,7 @@
return;
}
- getDisplay().positionChildAtBottom(this, reason);
+ getDisplay().positionStackAtBottom(this, reason);
if (task != null) {
positionChildAtBottom(task);
}
@@ -1848,8 +1847,8 @@
boolean shouldBeVisible = true;
final int windowingMode = getWindowingMode();
final boolean isAssistantType = isActivityTypeAssistant();
- for (int i = display.getChildCount() - 1; i >= 0; --i) {
- final ActivityStack other = display.getChildAt(i);
+ for (int i = display.getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack other = display.getStackAt(i);
final boolean hasRunningActivities = other.topRunningActivityLocked() != null;
if (other == this) {
// Should be visible if there is no other stack occluding it, unless it doesn't
@@ -3010,7 +3009,7 @@
if (index == 0) {
return false;
}
- final ActivityStack stackBehind = display.getChildAt(index - 1);
+ final ActivityStack stackBehind = display.getStackAt(index - 1);
return stackBehind.isActivityTypeStandard();
}
@@ -3768,7 +3767,7 @@
if (!hasChild()) {
// Stack is now empty...
- removeIfPossible();
+ removeIfPossible();
}
moveHomeStackToFrontIfNeeded(topFocused, display, reason);
@@ -3887,7 +3886,7 @@
// always on top windows. Since the position the stack should be inserted into is calculated
// properly in {@link ActivityDisplay#getTopInsertPosition()} in both cases, we can just
// request that the stack is put at top here.
- display.positionChildAtTop(this, false /* includingParents */);
+ display.positionStackAtTop(this, false /* includingParents */);
}
/** NOTE: Should only be called from {@link Task#reparent}. */
@@ -4019,7 +4018,7 @@
final Task task = mChildren.get(0);
setWindowingMode(WINDOWING_MODE_UNDEFINED);
- getDisplay().positionChildAtTop(this, false /* includingParents */);
+ getDisplay().positionStackAtTop(this, false /* includingParents */);
mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, this);
MetricsLoggerWrapper.logPictureInPictureFullScreen(mService.mContext,
@@ -4456,20 +4455,14 @@
}
}
- // TODO(display-unify): Remove after display unification.
- protected void onParentChanged(ActivityDisplay newParent, ActivityDisplay oldParent) {
- onParentChanged(
- newParent != null ? newParent.mDisplayContent : null,
- oldParent != null ? oldParent.mDisplayContent : null);
- }
-
@Override
protected void onParentChanged(
ConfigurationContainer newParent, ConfigurationContainer oldParent) {
+ // TODO(display-merge): Remove cast
final ActivityDisplay display = newParent != null
- ? ((WindowContainer) newParent).getDisplayContent().mActivityDisplay : null;
+ ? (ActivityDisplay) ((WindowContainer) newParent).getDisplayContent() : null;
final ActivityDisplay oldDisplay = oldParent != null
- ? ((WindowContainer) oldParent).getDisplayContent().mActivityDisplay : null;
+ ? (ActivityDisplay) ((WindowContainer) oldParent).getDisplayContent() : null;
mDisplayId = (display != null) ? display.mDisplayId : INVALID_DISPLAY;
mPrevDisplayId = (oldDisplay != null) ? oldDisplay.mDisplayId : INVALID_DISPLAY;
@@ -5646,14 +5639,14 @@
return shouldSleepActivities() || mService.mShuttingDown;
}
- public void writeToProto(ProtoOutputStream proto, long fieldId,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
final long token = proto.start(fieldId);
- writeToProtoInnerStackOnly(proto, STACK, logLevel);
+ dumpDebugInnerStackOnly(proto, STACK, logLevel);
proto.write(com.android.server.am.ActivityStackProto.ID, mStackId);
for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
final Task task = getChildAt(taskNdx);
- task.writeToProto(proto, com.android.server.am.ActivityStackProto.TASKS, logLevel);
+ task.dumpDebug(proto, com.android.server.am.ActivityStackProto.TASKS, logLevel);
}
if (mResumedActivity != null) {
mResumedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
@@ -5661,7 +5654,7 @@
proto.write(DISPLAY_ID, mDisplayId);
if (!matchParentBounds()) {
final Rect bounds = getRequestedOverrideBounds();
- bounds.writeToProto(proto, com.android.server.am.ActivityStackProto.BOUNDS);
+ bounds.dumpDebug(proto, com.android.server.am.ActivityStackProto.BOUNDS);
}
// TODO: Remove, no longer needed with windowingMode.
@@ -5670,26 +5663,26 @@
}
// TODO(proto-merge): Remove once protos for ActivityStack and TaskStack are merged.
- void writeToProtoInnerStackOnly(ProtoOutputStream proto, long fieldId,
+ void dumpDebugInnerStackOnly(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
return;
}
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
+ super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
proto.write(StackProto.ID, mStackId);
for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
- mChildren.get(taskNdx).writeToProtoInnerTaskOnly(proto, StackProto.TASKS, logLevel);
+ mChildren.get(taskNdx).dumpDebugInnerTaskOnly(proto, StackProto.TASKS, logLevel);
}
proto.write(FILLS_PARENT, matchParentBounds());
- getRawBounds().writeToProto(proto, StackProto.BOUNDS);
+ getRawBounds().dumpDebug(proto, StackProto.BOUNDS);
proto.write(DEFER_REMOVAL, mDeferRemoval);
proto.write(MINIMIZE_AMOUNT, mMinimizeAmount);
proto.write(ADJUSTED_FOR_IME, mAdjustedForIme);
proto.write(ADJUST_IME_AMOUNT, mAdjustImeAmount);
proto.write(ADJUST_DIVIDER_AMOUNT, mAdjustDividerAmount);
- mAdjustedBounds.writeToProto(proto, ADJUSTED_BOUNDS);
+ mAdjustedBounds.dumpDebug(proto, ADJUSTED_BOUNDS);
proto.write(ANIMATING_BOUNDS, mBoundsAnimating);
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index d98aa6f..7356368 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1500,13 +1500,11 @@
mRootActivityContainer.getActivityDisplay(toDisplayId);
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
- // Tell the display we are exiting split-screen mode.
- toDisplay.onExitingSplitScreenMode();
// We are moving all tasks from the docked stack to the fullscreen stack,
// which is dismissing the docked stack, so resize all other stacks to
// fullscreen here already so we don't end up with resize trashing.
- for (int i = toDisplay.getChildCount() - 1; i >= 0; --i) {
- final ActivityStack otherStack = toDisplay.getChildAt(i);
+ for (int i = toDisplay.getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack otherStack = toDisplay.getStackAt(i);
if (!otherStack.inSplitScreenSecondaryWindowingMode()) {
continue;
}
@@ -1654,8 +1652,8 @@
// screen controls and is also the same for all stacks.
final ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
final Rect otherTaskRect = new Rect();
- for (int i = display.getChildCount() - 1; i >= 0; --i) {
- final ActivityStack current = display.getChildAt(i);
+ for (int i = display.getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack current = display.getStackAt(i);
if (!current.inSplitScreenSecondaryWindowingMode()) {
continue;
}
@@ -1740,7 +1738,7 @@
* to the fullscreen stack. This is to guarantee that when we are removing a stack,
* that the client receives onStop() before it is reparented. We do this by detaching
* the stack from the display so that it will be considered invisible when
- * ensureActivitiesVisible() is called, and all of its activitys will be marked
+ * ensureActivitiesVisible() is called, and all of its activities will be marked
* invisible as well and added to the stopping list. After which we process the
* stopping list by handling the idle.
*/
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index d3fd450..695f58c 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -546,7 +546,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
for (PendingActivityLaunch activity: mPendingActivityLaunches) {
activity.r.writeIdentifierToProto(proto, fieldId);
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 8164bf4..baa2955 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1132,7 +1132,7 @@
request.outActivity[0] = mLastStartActivityRecord;
}
- return getExternalResult(mLastStartActivityResult);
+ return mLastStartActivityResult;
}
/**
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index d097368..efd21ec 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6917,7 +6917,7 @@
synchronized (mGlobalLock) {
// The output proto of "activity --proto activities"
// is ActivityManagerServiceDumpActivitiesProto
- mRootActivityContainer.writeToProto(proto,
+ mRootActivityContainer.dumpDebug(proto,
ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR,
WindowTraceLogLevel.ALL);
}
@@ -7098,7 +7098,7 @@
int wakeFullness, boolean testPssMode) {
synchronized (mGlobalLock) {
if (dumpPackage == null) {
- getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
+ getGlobalConfiguration().dumpDebug(proto, GLOBAL_CONFIGURATION);
proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
writeSleepStateToProto(proto, wakeFullness, testPssMode);
if (mRunningVoice != null) {
@@ -7106,11 +7106,11 @@
ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
mRunningVoice.toString());
- mVoiceWakeLock.writeToProto(
+ mVoiceWakeLock.dumpDebug(
proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
proto.end(vrToken);
}
- mVrController.writeToProto(proto,
+ mVrController.dumpDebug(proto,
ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
if (mController != null) {
final long token = proto.start(CONTROLLER);
@@ -7118,25 +7118,25 @@
proto.write(IS_A_MONKEY, mControllerIsAMonkey);
proto.end(token);
}
- mStackSupervisor.mGoingToSleepWakeLock.writeToProto(proto, GOING_TO_SLEEP);
- mStackSupervisor.mLaunchingActivityWakeLock.writeToProto(proto,
+ mStackSupervisor.mGoingToSleepWakeLock.dumpDebug(proto, GOING_TO_SLEEP);
+ mStackSupervisor.mLaunchingActivityWakeLock.dumpDebug(proto,
LAUNCHING_ACTIVITY);
}
if (mHomeProcess != null && (dumpPackage == null
|| mHomeProcess.mPkgList.contains(dumpPackage))) {
- mHomeProcess.writeToProto(proto, HOME_PROC);
+ mHomeProcess.dumpDebug(proto, HOME_PROC);
}
if (mPreviousProcess != null && (dumpPackage == null
|| mPreviousProcess.mPkgList.contains(dumpPackage))) {
- mPreviousProcess.writeToProto(proto, PREVIOUS_PROC);
+ mPreviousProcess.dumpDebug(proto, PREVIOUS_PROC);
proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
}
if (mHeavyWeightProcess != null && (dumpPackage == null
|| mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
- mHeavyWeightProcess.writeToProto(proto, HEAVY_WEIGHT_PROC);
+ mHeavyWeightProcess.dumpDebug(proto, HEAVY_WEIGHT_PROC);
}
for (Map.Entry<String, Integer> entry
@@ -7152,7 +7152,7 @@
}
if (mCurAppTimeTracker != null) {
- mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
+ mCurAppTimeTracker.dumpDebug(proto, CURRENT_TRACKER, true);
}
}
diff --git a/services/core/java/com/android/server/wm/AnimationAdapter.java b/services/core/java/com/android/server/wm/AnimationAdapter.java
index 278a9ba..1be3d61 100644
--- a/services/core/java/com/android/server/wm/AnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/AnimationAdapter.java
@@ -76,11 +76,11 @@
void dump(PrintWriter pw, String prefix);
- default void writeToProto(ProtoOutputStream proto, long fieldId) {
+ default void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- writeToProto(proto);
+ dumpDebug(proto);
proto.end(token);
}
- void writeToProto(ProtoOutputStream proto);
+ void dumpDebug(ProtoOutputStream proto);
}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index cd7c216..e0c5fd05 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -2142,7 +2142,7 @@
}
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(APP_TRANSITION_STATE, mAppTransitionState);
proto.write(LAST_USED_APP_TRANSITION, mLastUsedAppTransition);
diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java
index 05d5a5c..57cdb0b 100644
--- a/services/core/java/com/android/server/wm/BarController.java
+++ b/services/core/java/com/android/server/wm/BarController.java
@@ -339,7 +339,7 @@
throw new IllegalArgumentException("Unknown state " + state);
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(STATE, mState);
proto.write(TRANSIENT_STATE, mTransientBarState);
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 30f3bc5..bfa72e0 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -591,7 +591,7 @@
* @hide
*/
@CallSuper
- protected void writeToProto(ProtoOutputStream proto, long fieldId,
+ protected void dumpDebug(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
// Critical log level logs only visible elements to mitigate performance overheard
if (logLevel != WindowTraceLogLevel.ALL && !mHasOverrideConfiguration) {
@@ -599,11 +599,11 @@
}
final long token = proto.start(fieldId);
- mRequestedOverrideConfiguration.writeToProto(proto, OVERRIDE_CONFIGURATION,
+ mRequestedOverrideConfiguration.dumpDebug(proto, OVERRIDE_CONFIGURATION,
logLevel == WindowTraceLogLevel.CRITICAL);
if (logLevel == WindowTraceLogLevel.ALL) {
- mFullConfiguration.writeToProto(proto, FULL_CONFIGURATION, false /* critical */);
- mMergedOverrideConfiguration.writeToProto(proto, MERGED_OVERRIDE_CONFIGURATION,
+ mFullConfiguration.dumpDebug(proto, FULL_CONFIGURATION, false /* critical */);
+ mMergedOverrideConfiguration.dumpDebug(proto, MERGED_OVERRIDE_CONFIGURATION,
false /* critical */);
}
proto.end(token);
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index e6150cb..af859d3 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -389,7 +389,7 @@
}
@Override
- public void writeToProtoInner(ProtoOutputStream proto) {
+ public void dumpDebugInner(ProtoOutputStream proto) {
final long token = proto.start(ALPHA);
proto.write(FROM, mFromAlpha);
proto.write(TO, mToAlpha);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index b046b08..8e126b5 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -138,7 +138,6 @@
import static com.android.server.wm.utils.RegionUtils.rectListToRegion;
import android.animation.AnimationHandler;
-import android.annotation.CallSuper;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -221,7 +220,7 @@
* particular Display.
*/
class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer>
- implements WindowManagerPolicy.DisplayContentInfo, ConfigurationContainerListener {
+ implements WindowManagerPolicy.DisplayContentInfo {
private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
/** The default scaling mode that scales content automatically. */
@@ -236,11 +235,10 @@
@Retention(RetentionPolicy.SOURCE)
@interface ForceScalingMode {}
- /** Unique identifier of this stack. */
- private final int mDisplayId;
+ ActivityTaskManagerService mAtmService;
- // TODO: Remove once unification is complete.
- ActivityDisplay mActivityDisplay;
+ /** Unique identifier of this display. */
+ private final int mDisplayId;
/** The containers below are the only child containers the display can have. */
// Contains all window containers that are related to apps (Activities)
@@ -671,10 +669,12 @@
getDisplayPolicy().layoutWindowLw(w, null, mDisplayFrames);
w.mLayoutSeq = mLayoutSeq;
- // If this is the first layout, we need to initialize the last inset values as
- // otherwise we'd immediately cause an unnecessary resize.
+ // If this is the first layout, we need to initialize the last frames and inset values,
+ // as otherwise we'd immediately cause an unnecessary resize.
if (firstLayout) {
+ w.updateLastFrames();
w.updateLastInsetValues();
+ w.updateLocationInParentDisplayIfNeeded();
}
if (w.mActivityRecord != null) {
@@ -842,16 +842,15 @@
* @param service You know.
* @param activityDisplay The ActivityDisplay for the display container.
*/
- DisplayContent(Display display, WindowManagerService service,
- ActivityDisplay activityDisplay) {
+ DisplayContent(Display display, WindowManagerService service) {
super(service);
- mActivityDisplay = activityDisplay;
if (service.mRoot.getDisplayContent(display.getDisplayId()) != null) {
throw new IllegalArgumentException("Display with ID=" + display.getDisplayId()
+ " already exists=" + service.mRoot.getDisplayContent(display.getDisplayId())
+ " new=" + display);
}
+ mAtmService = mWmService.mAtmService;
mDisplay = display;
mDisplayId = display.getDisplayId();
mWallpaperController = new WallpaperController(mWmService, this);
@@ -1125,20 +1124,6 @@
mAppTransitionController.registerRemoteAnimations(definition);
}
- /**
- * The display content may have configuration set from {@link #DisplayWindowSettings}. This
- * callback let the owner of container know there is existing configuration to prevent the
- * values from being replaced by the initializing {@link #ActivityDisplay}.
- */
- void initializeDisplayOverrideConfiguration() {
- if (mActivityDisplay == null) {
- return;
- }
- mActivityDisplay.onRequestedOverrideConfigurationChanged(
- getResolvedOverrideConfiguration());
- mActivityDisplay.registerConfigurationChangeListener(this);
- }
-
void reconfigureDisplayLocked() {
if (!isReady()) {
return;
@@ -1162,13 +1147,15 @@
}
void sendNewConfiguration() {
- if (!isReady() || mActivityDisplay == null) {
+ if (!isReady()) {
return;
}
if (mDisplayRotation.isWaitingForRemoteRotation()) {
return;
}
- final boolean configUpdated = mActivityDisplay.updateDisplayOverrideConfigurationLocked();
+ // TODO(display-merge): Remove cast
+ final boolean configUpdated =
+ ((ActivityDisplay) this).updateDisplayOverrideConfigurationLocked();
if (configUpdated) {
return;
}
@@ -1199,7 +1186,8 @@
if (handled && requestingContainer instanceof ActivityRecord) {
final ActivityRecord activityRecord = (ActivityRecord) requestingContainer;
- final boolean kept = mActivityDisplay.updateDisplayOverrideConfigurationLocked(
+ // TODO(display-merge): Remove cast
+ final boolean kept = ((ActivityDisplay) this).updateDisplayOverrideConfigurationLocked(
config, activityRecord, false /* deferResume */, null /* result */);
activityRecord.frozenBeforeDestroy = true;
if (!kept) {
@@ -1208,7 +1196,8 @@
} else {
// We have a new configuration to push so we need to update ATMS for now.
// TODO: Clean up display configuration push between ATMS and WMS after unification.
- mActivityDisplay.updateDisplayOverrideConfigurationLocked(
+ // TODO(display-merge): Remove cast
+ ((ActivityDisplay) this.mDisplayContent).updateDisplayOverrideConfigurationLocked(
config, null /* starting */, false /* deferResume */, null);
}
return handled;
@@ -1797,12 +1786,15 @@
return mTaskStackContainers.getHomeStack();
}
+ ActivityStack getRecentsStack() {
+ return mTaskStackContainers.getRecentsStack();
+ }
+
/**
- * @return The primary split-screen stack, but only if it is visible, and {@code null} otherwise.
+ * @return The primary split-screen stack, and {@code null} otherwise.
*/
ActivityStack getSplitScreenPrimaryStack() {
- ActivityStack stack = mTaskStackContainers.getSplitScreenPrimaryStack();
- return (stack != null && stack.isVisible()) ? stack : null;
+ return mTaskStackContainers.getSplitScreenPrimaryStack();
}
boolean hasSplitScreenPrimaryStack() {
@@ -1841,6 +1833,22 @@
return mTaskStackContainers.getStack(windowingMode, activityType);
}
+ protected int getStackCount() {
+ return mTaskStackContainers.mChildren.size();
+ }
+
+ protected ActivityStack getStackAt(int index) {
+ return mTaskStackContainers.mChildren.get(index);
+ }
+
+ int getIndexOf(ActivityStack stack) {
+ return mTaskStackContainers.getIndexOf(stack);
+ }
+
+ void removeStack(ActivityStack stack) {
+ mTaskStackContainers.removeChild(stack);
+ }
+
@VisibleForTesting
WindowList<ActivityStack> getStacks() {
return mTaskStackContainers.mChildren;
@@ -2208,11 +2216,6 @@
stack.reparent(mTaskStackContainers, onTop ? POSITION_TOP: POSITION_BOTTOM);
}
- // TODO(display-unify): No longer needed then.
- void removeStackFromDisplay(ActivityStack stack) {
- mTaskStackContainers.removeChild(stack);
- }
-
@Override
protected void addChild(DisplayChildWindowContainer child,
Comparator<DisplayChildWindowContainer> comparator) {
@@ -2364,9 +2367,6 @@
void removeImmediately() {
mRemovingDisplay = true;
try {
- if (mActivityDisplay != null) {
- mActivityDisplay.unregisterConfigurationChangeListener(this);
- }
if (mParentWindow != null) {
mParentWindow.removeEmbeddedDisplayContent(this);
}
@@ -2386,7 +2386,9 @@
mWindowingLayer.release();
mOverlayLayer.release();
mInputMonitor.onDisplayRemoved();
- mWmService.mDisplayNotificationController.dispatchDisplayRemoved(mActivityDisplay);
+ // TODO(display-merge): Remove cast
+ mWmService.mDisplayNotificationController
+ .dispatchDisplayRemoved((ActivityDisplay) this);
} finally {
mDisplayReady = false;
mRemovingDisplay = false;
@@ -2599,9 +2601,8 @@
}
}
- @CallSuper
- @Override
- public void writeToProto(ProtoOutputStream proto, long fieldId,
+ // TODO(proto-merge): Remove once protos for ActivityDisplay and DisplayContent are merged.
+ public void dumpDebugInner(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
// Critical log level logs only visible elements to mitigate performance overheard
if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
@@ -2609,35 +2610,35 @@
}
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
+ super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
proto.write(ID, mDisplayId);
for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = mTaskStackContainers.getChildAt(stackNdx);
- stack.writeToProtoInnerStackOnly(proto, STACKS, logLevel);
+ stack.dumpDebugInnerStackOnly(proto, STACKS, logLevel);
}
- mDividerControllerLocked.writeToProto(proto, DOCKED_STACK_DIVIDER_CONTROLLER);
- mPinnedStackControllerLocked.writeToProto(proto, PINNED_STACK_CONTROLLER);
+ mDividerControllerLocked.dumpDebug(proto, DOCKED_STACK_DIVIDER_CONTROLLER);
+ mPinnedStackControllerLocked.dumpDebug(proto, PINNED_STACK_CONTROLLER);
for (int i = mAboveAppWindowsContainers.getChildCount() - 1; i >= 0; --i) {
final WindowToken windowToken = mAboveAppWindowsContainers.getChildAt(i);
- windowToken.writeToProto(proto, ABOVE_APP_WINDOWS, logLevel);
+ windowToken.dumpDebug(proto, ABOVE_APP_WINDOWS, logLevel);
}
for (int i = mBelowAppWindowsContainers.getChildCount() - 1; i >= 0; --i) {
final WindowToken windowToken = mBelowAppWindowsContainers.getChildAt(i);
- windowToken.writeToProto(proto, BELOW_APP_WINDOWS, logLevel);
+ windowToken.dumpDebug(proto, BELOW_APP_WINDOWS, logLevel);
}
for (int i = mImeWindowsContainers.getChildCount() - 1; i >= 0; --i) {
final WindowToken windowToken = mImeWindowsContainers.getChildAt(i);
- windowToken.writeToProto(proto, IME_WINDOWS, logLevel);
+ windowToken.dumpDebug(proto, IME_WINDOWS, logLevel);
}
proto.write(DPI, mBaseDisplayDensity);
- mDisplayInfo.writeToProto(proto, DISPLAY_INFO);
+ mDisplayInfo.dumpDebug(proto, DISPLAY_INFO);
proto.write(ROTATION, getRotation());
final ScreenRotationAnimation screenRotationAnimation = getRotationAnimation();
if (screenRotationAnimation != null) {
- screenRotationAnimation.writeToProto(proto, SCREEN_ROTATION_ANIMATION);
+ screenRotationAnimation.dumpDebug(proto, SCREEN_ROTATION_ANIMATION);
}
- mDisplayFrames.writeToProto(proto, DISPLAY_FRAMES);
- mAppTransition.writeToProto(proto, APP_TRANSITION);
+ mDisplayFrames.dumpDebug(proto, DISPLAY_FRAMES);
+ mAppTransition.dumpDebug(proto, APP_TRANSITION);
if (mFocusedApp != null) {
mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
}
@@ -3929,6 +3930,7 @@
// Cached reference to some special stacks we tend to get a lot so we don't need to loop
// through the list to find them.
private ActivityStack mHomeStack = null;
+ private ActivityStack mRecentsStack = null;
private ActivityStack mPinnedStack = null;
private ActivityStack mSplitScreenPrimaryStack = null;
@@ -3936,12 +3938,6 @@
super(service);
}
- @Override
- public void onConfigurationChanged(Configuration newParentConfig) {
- // TODO(display-unify): Remove after unification.
- onConfigurationChanged(newParentConfig, mActivityDisplay == null /*forwardToChildren*/);
- }
-
/**
* Returns the topmost stack on the display that is compatible with the input windowing mode
* and activity type. Null is no compatible stack on the display.
@@ -3976,6 +3972,10 @@
? mTaskStackContainers.getChildAt(mTaskStackContainers.getChildCount() - 1) : null;
}
+ int getIndexOf(ActivityStack stack) {
+ return mTaskStackContainers.mChildren.indexOf(stack);
+ }
+
ActivityStack getHomeStack() {
if (mHomeStack == null && mDisplayId == DEFAULT_DISPLAY) {
Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
@@ -3983,6 +3983,10 @@
return mHomeStack;
}
+ ActivityStack getRecentsStack() {
+ return mRecentsStack;
+ }
+
ActivityStack getPinnedStack() {
return mPinnedStack;
}
@@ -4018,6 +4022,13 @@
}
mHomeStack = stack;
+ } else if (stack.isActivityTypeRecents()) {
+ if (mRecentsStack != null && mRecentsStack != stack) {
+ throw new IllegalArgumentException(
+ "addStackReferenceIfNeeded: recents stack=" + mRecentsStack
+ + " already exist on display=" + this + " stack=" + stack);
+ }
+ mRecentsStack = stack;
}
final int windowingMode = stack.getWindowingMode();
if (windowingMode == WINDOWING_MODE_PINNED) {
@@ -4034,17 +4045,23 @@
+ " already exist on display=" + this + " stack=" + stack);
}
mSplitScreenPrimaryStack = stack;
+ // TODO(display-merge): Remove cast
+ ((ActivityDisplay) this.mDisplayContent).onSplitScreenModeActivated();
mDividerControllerLocked.notifyDockedStackExistsChanged(true);
}
}
- private void removeStackReferenceIfNeeded(ActivityStack stack) {
+ void removeStackReferenceIfNeeded(ActivityStack stack) {
if (stack == mHomeStack) {
mHomeStack = null;
+ } else if (stack == mRecentsStack) {
+ mRecentsStack = null;
} else if (stack == mPinnedStack) {
mPinnedStack = null;
} else if (stack == mSplitScreenPrimaryStack) {
mSplitScreenPrimaryStack = null;
+ // TODO(display-merge): Remove cast
+ ((ActivityDisplay) this.mDisplayContent).onSplitScreenModeDismissed();
// Re-set the split-screen create mode whenever the split-screen stack is removed.
mWmService.setDockedStackCreateStateLocked(
SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
@@ -4058,9 +4075,6 @@
position = findPositionForStack(position, stack, true /* adding */);
super.addChild(stack, position);
- if (mActivityDisplay != null) {
- mActivityDisplay.addChild(stack, position, true /*fromDc*/);
- }
// The reparenting case is handled in WindowContainer.
if (!stack.mReparenting) {
@@ -4072,9 +4086,8 @@
@Override
protected void removeChild(ActivityStack stack) {
super.removeChild(stack);
- if (mActivityDisplay != null) {
- mActivityDisplay.onChildRemoved(stack);
- }
+ // TODO(display-merge): Remove cast
+ ((ActivityDisplay) this.mDisplayContent).onStackRemoved(stack);
removeStackReferenceIfNeeded(stack);
}
@@ -4087,7 +4100,7 @@
@Override
void positionChildAt(int position, ActivityStack child, boolean includingParents) {
if (child.getWindowConfiguration().isAlwaysOnTop()
- && position != POSITION_TOP) {
+ && position != POSITION_TOP && position != mChildren.size()) {
// This stack is always-on-top, override the default behavior.
Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + this + " to bottom");
@@ -4097,7 +4110,11 @@
super.positionChildAt(currentPosition, child, false /* includingParents */);
return;
}
-
+ // We don't allow untrusted display to top when task stack moves to top,
+ // until user tapping this display to change display position as top intentionally.
+ if (isUntrustedVirtualDisplay() && !getParent().isOnTop()) {
+ includingParents = false;
+ }
final int targetPosition = findPositionForStack(position, child, false /* adding */);
super.positionChildAt(targetPosition, child, includingParents);
@@ -4133,7 +4150,12 @@
final int topChildPosition = mChildren.size() - 1;
int belowAlwaysOnTopPosition = POSITION_BOTTOM;
for (int i = topChildPosition; i >= 0; --i) {
- if (getStacks().get(i) != stack && !getStacks().get(i).isAlwaysOnTop()) {
+ // 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 = getStacks().get(i) == stack;
+ if ((sameStack && stack.isAlwaysOnTop())
+ || (!sameStack && !getStacks().get(i).isAlwaysOnTop())) {
belowAlwaysOnTopPosition = i;
break;
}
@@ -4158,10 +4180,6 @@
POSITION_BOTTOM ? belowAlwaysOnTopPosition : 0;
}
- int targetPosition = requestedPosition;
- targetPosition = Math.min(targetPosition, maxPosition);
- targetPosition = Math.max(targetPosition, minPosition);
-
// Cap the requested position to something reasonable for the previous position check
// below.
if (requestedPosition == POSITION_TOP) {
@@ -4170,6 +4188,10 @@
requestedPosition = 0;
}
+ int targetPosition = requestedPosition;
+ targetPosition = Math.min(targetPosition, maxPosition);
+ targetPosition = Math.max(targetPosition, minPosition);
+
int prevPosition = getStacks().indexOf(stack);
// The positions we calculated above (maxPosition, minPosition) do not take into
// consideration the following edge cases.
diff --git a/services/core/java/com/android/server/wm/DisplayFrames.java b/services/core/java/com/android/server/wm/DisplayFrames.java
index 6b47c8a..f8495b5 100644
--- a/services/core/java/com/android/server/wm/DisplayFrames.java
+++ b/services/core/java/com/android/server/wm/DisplayFrames.java
@@ -152,9 +152,9 @@
return mDock.bottom - mCurrent.bottom;
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- mStable.writeToProto(proto, STABLE_BOUNDS);
+ mStable.dumpDebug(proto, STABLE_BOUNDS);
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 77e557b..2283041 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2215,9 +2215,22 @@
}
private void offsetInputMethodWindowLw(WindowState win, DisplayFrames displayFrames) {
+ final int rotation = displayFrames.mRotation;
+ final int navBarPosition = navigationBarPosition(displayFrames.mDisplayWidth,
+ displayFrames.mDisplayHeight, rotation);
+
int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top);
top += win.getGivenContentInsetsLw().top;
displayFrames.mContent.bottom = Math.min(displayFrames.mContent.bottom, top);
+ if (navBarPosition == NAV_BAR_BOTTOM) {
+ // Always account for the nav bar frame height on the bottom since in all navigation
+ // modes we make room to show the dismiss-ime button, even if the IME does not report
+ // insets (ie. when floating)
+ final int uimode = mService.mPolicy.getUiMode();
+ final int navFrameHeight = getNavigationBarFrameHeight(rotation, uimode);
+ displayFrames.mContent.bottom = Math.min(displayFrames.mContent.bottom,
+ displayFrames.mUnrestricted.bottom - navFrameHeight);
+ }
displayFrames.mVoiceContent.bottom = Math.min(displayFrames.mVoiceContent.bottom, top);
top = win.getVisibleFrameLw().top;
top += win.getGivenVisibleInsetsLw().top;
diff --git a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
index 2da76ea..78fea74 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
@@ -63,7 +63,7 @@
mDisplayListeners.finishBroadcast();
}
- void dispatchDisplayChanged(ActivityDisplay display, Configuration newConfig) {
+ void dispatchDisplayChanged(DisplayContent display, Configuration newConfig) {
// Only report changed if this has actually been added to the hierarchy already.
boolean isInHierarchy = false;
for (int i = 0; i < display.getParent().getChildCount(); ++i) {
@@ -78,7 +78,7 @@
for (int i = 0; i < count; ++i) {
try {
mDisplayListeners.getBroadcastItem(i).onDisplayConfigurationChanged(
- display.mDisplayId, newConfig);
+ display.getDisplayId(), newConfig);
} catch (RemoteException e) {
}
}
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 07d5094..1a1a7d4 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -1018,7 +1018,7 @@
pw.println(prefix + " mAdjustedForDivider=" + mAdjustedForDivider);
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(MINIMIZED_DOCK, mMinimizedDock);
proto.end(token);
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index b4055545..69e8fdc 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -293,7 +293,7 @@
}
@Override
- public void writeToProto(ProtoOutputStream proto) {
+ public void dumpDebug(ProtoOutputStream proto) {
}
}
}
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 7645de5..ac5c96b 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -531,8 +531,8 @@
* occlusion state.
*/
private ActivityStack getStackForControllingOccluding(ActivityDisplay display) {
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
if (stack != null && stack.isFocusableAndVisible()
&& !stack.inPinnedWindowingMode()) {
return stack;
@@ -552,7 +552,7 @@
pw.println(sb.toString());
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(DISPLAY_ID, mDisplayId);
proto.write(KEYGUARD_OCCLUDED, mOccluded);
@@ -570,7 +570,7 @@
pw.println(prefix + " mVisibilityTransactionDepth=" + mVisibilityTransactionDepth);
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(AOD_SHOWING, mAodShowing);
proto.write(KEYGUARD_SHOWING, mKeyguardShowing);
@@ -586,7 +586,7 @@
private void writeDisplayStatesToProto(ProtoOutputStream proto, long fieldId) {
for (int i = 0; i < mDisplayStates.size(); i++) {
- mDisplayStates.valueAt(i).writeToProto(proto, fieldId);
+ mDisplayStates.valueAt(i).dumpDebug(proto, fieldId);
}
}
}
diff --git a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
index e67cb6fc..5892239 100644
--- a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
@@ -76,9 +76,9 @@
}
@Override
- public void writeToProto(ProtoOutputStream proto) {
+ public void dumpDebug(ProtoOutputStream proto) {
final long token = proto.start(LOCAL);
- mSpec.writeToProto(proto, ANIMATION_SPEC);
+ mSpec.dumpDebug(proto, ANIMATION_SPEC);
proto.end(token);
}
@@ -131,12 +131,12 @@
void dump(PrintWriter pw, String prefix);
- default void writeToProto(ProtoOutputStream proto, long fieldId) {
+ default void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- writeToProtoInner(proto);
+ dumpDebugInner(proto);
proto.end(token);
}
- void writeToProtoInner(ProtoOutputStream proto);
+ void dumpDebugInner(ProtoOutputStream proto);
}
}
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 0853f1f..a8e7aea 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -604,11 +604,11 @@
pw.println(prefix + " mDisplayInfo=" + mDisplayInfo);
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- getDefaultBounds(INVALID_SNAP_FRACTION).writeToProto(proto, DEFAULT_BOUNDS);
+ getDefaultBounds(INVALID_SNAP_FRACTION).dumpDebug(proto, DEFAULT_BOUNDS);
mService.getStackBounds(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mTmpRect);
- getMovementBounds(mTmpRect).writeToProto(proto, MOVEMENT_BOUNDS);
+ getMovementBounds(mTmpRect).dumpDebug(proto, MOVEMENT_BOUNDS);
proto.end(token);
}
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index f4c867c..d5bbe6b 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -475,8 +475,8 @@
* @return The top stack that is not always-on-top.
*/
private ActivityStack getTopNonAlwaysOnTopStack() {
- for (int i = mDefaultDisplay.getChildCount() - 1; i >= 0; i--) {
- final ActivityStack s = mDefaultDisplay.getChildAt(i);
+ for (int i = mDefaultDisplay.getStackCount() - 1; i >= 0; i--) {
+ final ActivityStack s = mDefaultDisplay.getStackAt(i);
if (s.getWindowConfiguration().isAlwaysOnTop()) {
continue;
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 39d08a2..39091a6 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -910,10 +910,10 @@
}
@Override
- public void writeToProto(ProtoOutputStream proto) {
+ public void dumpDebug(ProtoOutputStream proto) {
final long token = proto.start(REMOTE);
if (mTarget != null) {
- mTarget.writeToProto(proto, TARGET);
+ mTarget.dumpDebug(proto, TARGET);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index efd1241..0b9be1a 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -464,10 +464,10 @@
}
@Override
- public void writeToProto(ProtoOutputStream proto) {
+ public void dumpDebug(ProtoOutputStream proto) {
final long token = proto.start(REMOTE);
if (mRecord.mTarget != null) {
- mRecord.mTarget.writeToProto(proto, TARGET);
+ mRecord.mTarget.dumpDebug(proto, TARGET);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 5fd59fa..5653ec0 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -52,7 +52,6 @@
import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
@@ -770,10 +769,12 @@
starting.frozenBeforeDestroy = true;
}
- if (displayContent != null && displayContent.mActivityDisplay != null) {
+ if (displayContent != null) {
// Update the configuration of the activities on the display.
- return displayContent.mActivityDisplay.updateDisplayOverrideConfigurationLocked(config,
- starting, deferResume, null /* result */);
+ // TODO(display-merge): Remove cast
+ return ((ActivityDisplay) displayContent)
+ .updateDisplayOverrideConfigurationLocked(config, starting, deferResume,
+ null /* result */);
} else {
return true;
}
@@ -790,8 +791,8 @@
for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
final ActivityDisplay display = mActivityDisplays.get(i);
// Traverse all stacks on a display.
- for (int j = display.getChildCount() - 1; j >= 0; --j) {
- final ActivityStack stack = display.getChildAt(j);
+ for (int j = display.getStackCount() - 1; j >= 0; --j) {
+ final ActivityStack stack = display.getStackAt(j);
// Get top activity from a visible stack and add it to the list.
if (stack.shouldBeVisible(null /* starting */)) {
final ActivityRecord top = stack.getTopNonFinishingActivity();
@@ -861,8 +862,8 @@
WindowProcessController fgApp = null;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
if (isTopDisplayFocusedStack(stack)) {
final ActivityRecord resumedActivity = stack.getResumedActivity();
if (resumedActivity != null) {
@@ -988,8 +989,8 @@
mStackSupervisor.mStartingUsers.add(uss);
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
stack.switchUser(userId);
Task task = stack.topTask();
if (task != null) {
@@ -1056,7 +1057,7 @@
+ " to its current displayId=" + displayId);
}
- if (activityDisplay.isSingleTaskInstance() && activityDisplay.getChildCount() > 0) {
+ if (activityDisplay.isSingleTaskInstance() && activityDisplay.getStackCount() > 0) {
// We don't allow moving stacks to single instance display that already has a child.
Slog.e(TAG, "Can not move stack=" + stack
+ " to single task instance display=" + activityDisplay);
@@ -1229,8 +1230,8 @@
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
// It is possible that request to finish activity might also remove its task and stack,
// so we need to be careful with indexes in the loop and check child count every time.
- for (int stackNdx = 0; stackNdx < display.getChildCount(); ++stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = 0; stackNdx < display.getStackCount(); ++stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
final Task t = stack.finishTopCrashedActivityLocked(app, reason);
if (stack == focusedStack || finishedTask == null) {
finishedTask = t;
@@ -1260,8 +1261,8 @@
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
boolean resumedOnDisplay = false;
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
final ActivityRecord topRunningActivity = stack.topRunningActivityLocked();
if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
continue;
@@ -1314,8 +1315,8 @@
}
// Set the sleeping state of the stacks on the display.
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
if (displayShouldSleep) {
stack.goToSleepIfPossible(false /* shuttingDown */);
} else {
@@ -1355,9 +1356,9 @@
}
}
- protected <T extends ActivityStack> T getStack(int stackId) {
+ protected ActivityStack getStack(int stackId) {
for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
- final T stack = mActivityDisplays.get(i).getStack(stackId);
+ final ActivityStack stack = mActivityDisplays.get(i).getStack(stackId);
if (stack != null) {
return stack;
}
@@ -1366,9 +1367,10 @@
}
/** @see ActivityDisplay#getStack(int, int) */
- private <T extends ActivityStack> T getStack(int windowingMode, int activityType) {
+ ActivityStack getStack(int windowingMode, int activityType) {
for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
- final T stack = mActivityDisplays.get(i).getStack(windowingMode, activityType);
+ final ActivityStack stack =
+ mActivityDisplays.get(i).getStack(windowingMode, activityType);
if (stack != null) {
return stack;
}
@@ -1376,7 +1378,7 @@
return null;
}
- private <T extends ActivityStack> T getStack(int windowingMode, int activityType,
+ private ActivityStack getStack(int windowingMode, int activityType,
int displayId) {
ActivityDisplay display = getActivityDisplay(displayId);
if (display == null) {
@@ -1449,8 +1451,8 @@
if (displayId == INVALID_DISPLAY) {
for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
list.add(getStackInfo(stack));
}
}
@@ -1460,8 +1462,8 @@
if (display == null) {
return list;
}
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
list.add(getStackInfo(stack));
}
return list;
@@ -1549,9 +1551,9 @@
ActivityStack findStackBehind(ActivityStack stack) {
final ActivityDisplay display = getActivityDisplay(stack.mDisplayId);
if (display != null) {
- for (int i = display.getChildCount() - 1; i >= 0; i--) {
- if (display.getChildAt(i) == stack && i > 0) {
- return display.getChildAt(i - 1);
+ for (int i = display.getStackCount() - 1; i >= 0; i--) {
+ if (display.getStackAt(i) == stack && i > 0) {
+ return display.getStackAt(i - 1);
}
}
}
@@ -1575,7 +1577,7 @@
}
// TODO: remove after object merge with RootWindowContainer
- void onChildPositionChanged(ActivityDisplay display, int position) {
+ void onChildPositionChanged(DisplayContent display, int position) {
// Assume AM lock is held from positionChildAt of controller in each hierarchy.
if (display != null) {
positionChildAt(display, position);
@@ -1583,18 +1585,20 @@
}
/** Change the z-order of the given display. */
- private void positionChildAt(ActivityDisplay display, int position) {
+ private void positionChildAt(DisplayContent display, int position) {
if (position >= mActivityDisplays.size()) {
position = mActivityDisplays.size() - 1;
} else if (position < 0) {
position = 0;
}
+ // TODO(display-merge): Remove cast
+ final ActivityDisplay activityDisplay = (ActivityDisplay) display;
if (mActivityDisplays.isEmpty()) {
- mActivityDisplays.add(display);
+ mActivityDisplays.add(activityDisplay);
} else if (mActivityDisplays.get(position) != display) {
mActivityDisplays.remove(display);
- mActivityDisplays.add(position, display);
+ mActivityDisplays.add(position, activityDisplay);
}
mStackSupervisor.updateTopResumedActivityIfNeeded();
}
@@ -1709,8 +1713,8 @@
void scheduleDestroyAllActivities(WindowProcessController app, String reason) {
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
stack.scheduleDestroyActivities(app, reason);
}
}
@@ -1722,15 +1726,15 @@
boolean allSleep = true;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
// Stacks and activities could be removed while putting activities to sleep if
// the app process was gone. This prevents us getting exception by accessing an
// invalid stack index.
- if (stackNdx >= display.getChildCount()) {
+ if (stackNdx >= display.getStackCount()) {
continue;
}
- final ActivityStack stack = display.getChildAt(stackNdx);
+ final ActivityStack stack = display.getStackAt(stackNdx);
if (allowDelay) {
allSleep &= stack.goToSleepIfPossible(shuttingDown);
} else {
@@ -1972,8 +1976,8 @@
r.getActivityType());
// Return the topmost valid stack on the display.
- for (int i = activityDisplay.getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = activityDisplay.getChildAt(i);
+ for (int i = activityDisplay.getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack stack = activityDisplay.getStackAt(i);
if (isValidLaunchStack(stack, r, windowingMode)) {
return stack;
}
@@ -2110,8 +2114,8 @@
boolean hasVisibleActivities = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
hasVisibleActivities |= stack.handleAppDiedLocked(app);
}
}
@@ -2223,9 +2227,9 @@
void finishVoiceTask(IVoiceInteractionSession session) {
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- final int numStacks = display.getChildCount();
+ final int numStacks = display.getStackCount();
for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ final ActivityStack stack = display.getStackAt(stackNdx);
stack.finishVoiceTask(session);
}
}
@@ -2290,8 +2294,8 @@
boolean foundResumed = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
final ActivityRecord r = stack.getResumedActivity();
if (r != null) {
if (!r.nowVisible) {
@@ -2308,8 +2312,8 @@
boolean pausing = true;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
final ActivityRecord r = stack.mPausingActivity;
if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) {
if (DEBUG_STATES) {
@@ -2336,8 +2340,8 @@
try {
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
final List<Task> tasks = stack.getAllTasks();
for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
final Task task = tasks.get(taskNdx);
@@ -2380,8 +2384,8 @@
void cancelInitializingActivities() {
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
stack.cancelInitializingActivities();
}
}
@@ -2413,8 +2417,8 @@
int numDisplays = mActivityDisplays.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
final Task task = stack.taskForIdLocked(id);
if (task == null) {
continue;
@@ -2471,8 +2475,8 @@
int numDisplays = mActivityDisplays.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
final ActivityRecord r = stack.isInStackLocked(token);
if (r != null) {
return r;
@@ -2554,8 +2558,8 @@
int numDisplays = mActivityDisplays.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
activities.addAll(stack.getDumpActivitiesLocked(name));
}
@@ -2606,8 +2610,8 @@
pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
pw.println(" (activities from top to bottom):");
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
pw.println();
printed = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, needSep);
needSep = printed;
@@ -2629,15 +2633,15 @@
return printed;
}
- protected void writeToProto(ProtoOutputStream proto, long fieldId,
+ protected void dumpDebug(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
final long token = proto.start(fieldId);
- super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
+ super.dumpDebug(proto, CONFIGURATION_CONTAINER, logLevel);
for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
- activityDisplay.writeToProto(proto, DISPLAYS, logLevel);
+ activityDisplay.dumpDebug(proto, DISPLAYS, logLevel);
}
- mStackSupervisor.getKeyguardController().writeToProto(proto, KEYGUARD_CONTROLLER);
+ mStackSupervisor.getKeyguardController().dumpDebug(proto, KEYGUARD_CONTROLLER);
// TODO(b/111541062): Update tests to look for resumed activities on all displays
final ActivityStack focusedStack = getTopDisplayFocusedStack();
if (focusedStack != null) {
@@ -2651,7 +2655,7 @@
}
proto.write(IS_HOME_RECENTS_COMPONENT,
mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
- mService.getActivityStartController().writeToProto(proto, PENDING_ACTIVITIES);
+ mService.getActivityStartController().dumpDebug(proto, PENDING_ACTIVITIES);
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 5ec9599..361bbe4 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -37,7 +37,6 @@
import static com.android.server.wm.RootWindowContainerProto.DISPLAYS;
import static com.android.server.wm.RootWindowContainerProto.WINDOWS;
import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
@@ -71,7 +70,6 @@
import android.util.Slog;
import android.util.SparseIntArray;
import android.util.proto.ProtoOutputStream;
-import android.view.Display;
import android.view.DisplayInfo;
import android.view.SurfaceControl;
import android.view.WindowManager;
@@ -204,6 +202,12 @@
}
@Override
+ boolean isOnTop() {
+ // Considered always on top
+ return true;
+ }
+
+ @Override
void onChildPositionChanged(WindowContainer child) {
mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
!mWmService.mPerDisplayFocusEnabled /* updateInputWindows */);
@@ -219,36 +223,6 @@
return null;
}
- DisplayContent createDisplayContent(final Display display, ActivityDisplay activityDisplay) {
- final int displayId = display.getDisplayId();
-
- // In select scenarios, it is possible that a DisplayContent will be created on demand
- // rather than waiting for the controller. In this case, associate the controller and return
- // the existing display.
- final DisplayContent existing = getDisplayContent(displayId);
-
- if (existing != null) {
- existing.mActivityDisplay = activityDisplay;
- existing.initializeDisplayOverrideConfiguration();
- return existing;
- }
-
- final DisplayContent dc = new DisplayContent(display, mWmService, activityDisplay);
-
- if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
-
- mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(dc);
- dc.initializeDisplayOverrideConfiguration();
-
- if (mWmService.mDisplayManagerInternal != null) {
- mWmService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
- displayId, dc.getDisplayInfo());
- dc.configureDisplayPolicy();
- }
-
- return dc;
- }
-
/**
* Called when DisplayWindowSettings values may change.
*/
@@ -262,7 +236,6 @@
continue;
}
- displayContent.initializeDisplayOverrideConfiguration();
displayContent.reconfigureDisplayLocked();
// We need to update global configuration as well if config of default display has
@@ -1027,19 +1000,19 @@
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
return;
}
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
+ super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
if (mWmService.mDisplayReady) {
final int count = mChildren.size();
for (int i = 0; i < count; ++i) {
final DisplayContent displayContent = mChildren.get(i);
- displayContent.writeToProto(proto, DISPLAYS, logLevel);
+ displayContent.dumpDebugInner(proto, DISPLAYS, logLevel);
}
}
if (logLevel == WindowTraceLogLevel.ALL) {
@@ -1059,7 +1032,7 @@
void positionChildAt(int position, DisplayContent child, boolean includingParents) {
super.positionChildAt(position, child, includingParents);
if (mRootActivityContainer != null) {
- mRootActivityContainer.onChildPositionChanged(child.mActivityDisplay, position);
+ mRootActivityContainer.onChildPositionChanged(child, position);
}
}
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index f2678bb..ca9d91e 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -52,8 +52,8 @@
final int numDisplays = activityDisplays.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
final ActivityDisplay display = activityDisplays.get(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
+ for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = display.getStackAt(stackNdx);
mTmpStackTasks.clear();
stack.getRunningTasks(mTmpStackTasks, ignoreActivityType, ignoreWindowingMode,
callingUid, allowed, crossUser, profileIds);
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index c19c96f..1a7d214 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -244,7 +244,7 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(STARTED, mStarted);
proto.write(ANIMATION_RUNNING, mAnimRunning);
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index ba728ba..976730e 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -340,13 +340,13 @@
* @param fieldId Field Id of the SurfaceAnimator as defined in the parent message.
* @hide
*/
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
if (mAnimation != null) {
- mAnimation.writeToProto(proto, ANIMATION_ADAPTER);
+ mAnimation.dumpDebug(proto, ANIMATION_ADAPTER);
}
if (mLeash != null) {
- mLeash.writeToProto(proto, LEASH);
+ mLeash.dumpDebug(proto, LEASH);
}
proto.write(ANIMATION_START_DELAYED, mAnimationStartDelayed);
proto.end(token);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 88a38e0..b1d0692 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -968,6 +968,11 @@
final ActivityStack oldStack = ((ActivityStack) oldParent);
final ActivityStack newStack = ((ActivityStack) newParent);
+ // Task is going to be removed, clean it up before detaching from hierarchy.
+ if (oldParent != null && newParent == null) {
+ cleanUpResourcesForDestroy();
+ }
+
mStack = newStack;
super.onParentChanged(newParent, oldParent);
@@ -1012,12 +1017,6 @@
updateOverrideConfigurationFromLaunchBounds();
}
- // Task is being removed.
- if (oldParent != null && newParent == null) {
- cleanUpResourcesForDestroy();
- }
-
-
// Update task bounds if needed.
adjustBoundsForDisplayChangeIfNeeded(getDisplayContent());
@@ -2722,21 +2721,21 @@
}
// TODO(proto-merge): Remove once protos for TaskRecord and Task are merged.
- void writeToProtoInnerTaskOnly(ProtoOutputStream proto, long fieldId,
+ void dumpDebugInnerTaskOnly(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
return;
}
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
+ super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
proto.write(TaskProto.ID, mTaskId);
forAllActivities((r) -> {
- r.writeToProto(proto, APP_WINDOW_TOKENS, logLevel);
+ r.dumpDebug(proto, APP_WINDOW_TOKENS, logLevel);
});
proto.write(FILLS_PARENT, matchParentBounds());
- getBounds().writeToProto(proto, TaskProto.BOUNDS);
- mOverrideDisplayedBounds.writeToProto(proto, DISPLAYED_BOUNDS);
+ getBounds().dumpDebug(proto, TaskProto.BOUNDS);
+ mOverrideDisplayedBounds.dumpDebug(proto, DISPLAYED_BOUNDS);
if (mSurfaceControl != null) {
proto.write(SURFACE_WIDTH, mSurfaceControl.getWidth());
proto.write(SURFACE_HEIGHT, mSurfaceControl.getHeight());
@@ -2931,22 +2930,22 @@
}
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
return;
}
final long token = proto.start(fieldId);
- writeToProtoInnerTaskOnly(proto, TASK, logLevel);
+ dumpDebugInnerTaskOnly(proto, TASK, logLevel);
proto.write(com.android.server.am.TaskRecordProto.ID, mTaskId);
forAllActivities((r) -> {
- r.writeToProto(proto, ACTIVITIES);
+ r.dumpDebug(proto, ACTIVITIES);
});
proto.write(STACK_ID, getStackId());
if (mLastNonFullscreenBounds != null) {
- mLastNonFullscreenBounds.writeToProto(proto, LAST_NON_FULLSCREEN_BOUNDS);
+ mLastNonFullscreenBounds.dumpDebug(proto, LAST_NON_FULLSCREEN_BOUNDS);
}
if (realActivity != null) {
proto.write(REAL_ACTIVITY, realActivity.flattenToShortString());
@@ -2961,7 +2960,7 @@
if (!matchParentBounds()) {
final Rect bounds = getRequestedOverrideBounds();
- bounds.writeToProto(proto, com.android.server.am.TaskRecordProto.BOUNDS);
+ bounds.dumpDebug(proto, com.android.server.am.TaskRecordProto.BOUNDS);
}
proto.write(MIN_WIDTH, mMinWidth);
proto.write(MIN_HEIGHT, mMinHeight);
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index 8ad8972..9d19cfe 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -705,8 +705,8 @@
private void adjustBoundsToAvoidConflictInDisplay(@NonNull ActivityDisplay display,
@NonNull Rect inOutBounds) {
final List<Rect> taskBoundsToCheck = new ArrayList<>();
- for (int i = 0; i < display.getChildCount(); ++i) {
- final ActivityStack stack = display.getChildAt(i);
+ for (int i = 0; i < display.getStackCount(); ++i) {
+ final ActivityStack stack = display.getStackAt(i);
if (!stack.inFreeformWindowingMode()) {
continue;
}
diff --git a/services/core/java/com/android/server/wm/VrController.java b/services/core/java/com/android/server/wm/VrController.java
index 3e136d35..54cac38 100644
--- a/services/core/java/com/android/server/wm/VrController.java
+++ b/services/core/java/com/android/server/wm/VrController.java
@@ -441,7 +441,7 @@
return String.format("[VrState=0x%x,VrRenderThreadTid=%d]", mVrState, mVrRenderThreadTid);
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, VrControllerProto.VR_MODE,
mVrState, ORIG_ENUMS, PROTO_ENUMS);
diff --git a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
index 513008d..801e521 100644
--- a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
@@ -165,10 +165,10 @@
}
@Override
- public void writeToProto(ProtoOutputStream proto) {
+ public void dumpDebug(ProtoOutputStream proto) {
final long token = proto.start(REMOTE);
if (mTarget != null) {
- mTarget.writeToProto(proto, TARGET);
+ mTarget.dumpDebug(proto, TARGET);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimationSpec.java b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
index 7c183a8..06bffd4 100644
--- a/services/core/java/com/android/server/wm/WindowAnimationSpec.java
+++ b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
@@ -149,7 +149,7 @@
}
@Override
- public void writeToProtoInner(ProtoOutputStream proto) {
+ public void dumpDebugInner(ProtoOutputStream proto) {
final long token = proto.start(WINDOW);
proto.write(ANIMATION, mAnimation.toString());
proto.end(token);
diff --git a/services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java b/services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java
index d5d4e08..d3530c5 100644
--- a/services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java
+++ b/services/core/java/com/android/server/wm/WindowChangeAnimationSpec.java
@@ -186,7 +186,7 @@
}
@Override
- public void writeToProtoInner(ProtoOutputStream proto) {
+ public void dumpDebugInner(ProtoOutputStream proto) {
final long token = proto.start(WINDOW);
proto.write(ANIMATION, mAnimation.toString());
proto.end(token);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 5c1491e..e80f3b8 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -288,10 +288,8 @@
final DisplayContent dc = newParent.getDisplayContent();
mReparenting = true;
- // Oddly enough we add to the new parent before removing from the old parent to avoid
- // issues...
- newParent.addChild(this, position);
oldParent.removeChild(this);
+ newParent.addChild(this, position);
mReparenting = false;
// Relayout display(s)
@@ -1580,7 +1578,7 @@
*/
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
boolean isVisible = isVisible();
if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible) {
@@ -1588,11 +1586,11 @@
}
final long token = proto.start(fieldId);
- super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
+ super.dumpDebug(proto, CONFIGURATION_CONTAINER, logLevel);
proto.write(ORIENTATION, mOrientation);
proto.write(VISIBLE, isVisible);
if (mSurfaceAnimator.isAnimating()) {
- mSurfaceAnimator.writeToProto(proto, SURFACE_ANIMATOR);
+ mSurfaceAnimator.dumpDebug(proto, SURFACE_ANIMATOR);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
index 604eae6..8e070f1 100644
--- a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
+++ b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
@@ -166,12 +166,12 @@
* message.
* @hide
*/
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(WIDTH, mWidth);
proto.write(HEIGHT, mHeight);
if (mSurfaceAnimator.isAnimating()) {
- mSurfaceAnimator.writeToProto(proto, SURFACE_ANIMATOR);
+ mSurfaceAnimator.dumpDebug(proto, SURFACE_ANIMATOR);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java
index bafa38c..0490bac 100644
--- a/services/core/java/com/android/server/wm/WindowFrames.java
+++ b/services/core/java/com/android/server/wm/WindowFrames.java
@@ -334,19 +334,19 @@
return mContentChanged;
}
- public void writeToProto(@NonNull ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- mParentFrame.writeToProto(proto, PARENT_FRAME);
- mContentFrame.writeToProto(proto, CONTENT_FRAME);
- mDisplayFrame.writeToProto(proto, DISPLAY_FRAME);
- mVisibleFrame.writeToProto(proto, VISIBLE_FRAME);
- mDecorFrame.writeToProto(proto, DECOR_FRAME);
- mContainingFrame.writeToProto(proto, CONTAINING_FRAME);
- mFrame.writeToProto(proto, FRAME);
- mDisplayCutout.getDisplayCutout().writeToProto(proto, CUTOUT);
- mContentInsets.writeToProto(proto, CONTENT_INSETS);
- mVisibleInsets.writeToProto(proto, VISIBLE_INSETS);
- mStableInsets.writeToProto(proto, STABLE_INSETS);
+ mParentFrame.dumpDebug(proto, PARENT_FRAME);
+ mContentFrame.dumpDebug(proto, CONTENT_FRAME);
+ mDisplayFrame.dumpDebug(proto, DISPLAY_FRAME);
+ mVisibleFrame.dumpDebug(proto, VISIBLE_FRAME);
+ mDecorFrame.dumpDebug(proto, DECOR_FRAME);
+ mContainingFrame.dumpDebug(proto, CONTAINING_FRAME);
+ mFrame.dumpDebug(proto, FRAME);
+ mDisplayCutout.getDisplayCutout().dumpDebug(proto, CUTOUT);
+ mContentInsets.dumpDebug(proto, CONTENT_INSETS);
+ mVisibleInsets.dumpDebug(proto, VISIBLE_INSETS);
+ mStableInsets.dumpDebug(proto, STABLE_INSETS);
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 46faf3b..ea90e49 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -550,4 +550,10 @@
* the next time the activities are opened.
*/
public abstract void clearSnapshotCache();
+
+ /**
+ * Assigns accessibility ID a window surface as a layer metadata.
+ */
+ public abstract void setAccessibilityIdToSurfaceMetadata(
+ IBinder windowToken, int accessibilityWindowId);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4ec50f0..95eb4dd 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1732,20 +1732,7 @@
}
}
- DisplayContent displayContent = mRoot.getDisplayContent(displayId);
-
- // Create an instance if possible instead of waiting for the ActivityManagerService to drive
- // the creation.
- if (displayContent == null) {
- final Display display = mDisplayManager.getDisplay(displayId);
-
- if (display != null) {
- displayContent = mRoot.createDisplayContent(display, null /* activityDisplay */);
- displayContent.reconfigureDisplayLocked();
- }
- }
-
- return displayContent;
+ return mAtmService.mRootActivityContainer.getActivityDisplayOrCreate(displayId);
}
private boolean doesAddToastWindowRequireToken(String packageName, int callingUid,
@@ -2350,9 +2337,8 @@
win.setLastReportedMergedConfiguration(mergedConfiguration);
- // Update the last frames and inset values here because the values are sent back to the
- // client. The last values represent the last client state.
- win.updateLastFrames();
+ // Update the last inset values here because the values are sent back to the client.
+ // The last inset values represent the last client state
win.updateLastInsetValues();
win.getCompatFrame(outFrame);
@@ -5780,9 +5766,9 @@
* @param proto Stream to write the WindowContainer object to.
* @param logLevel Determines the amount of data to be written to the Protobuf.
*/
- void writeToProtoLocked(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel) {
- mPolicy.writeToProto(proto, POLICY);
- mRoot.writeToProto(proto, ROOT_WINDOW_CONTAINER, logLevel);
+ void dumpDebugLocked(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel) {
+ mPolicy.dumpDebug(proto, POLICY);
+ mRoot.dumpDebug(proto, ROOT_WINDOW_CONTAINER, logLevel);
final DisplayContent topFocusedDisplayContent = mRoot.getTopFocusedDisplayContent();
if (topFocusedDisplayContent.mCurrentFocus != null) {
topFocusedDisplayContent.mCurrentFocus.writeIdentifierToProto(proto, FOCUSED_WINDOW);
@@ -6105,7 +6091,7 @@
if (useProto) {
final ProtoOutputStream proto = new ProtoOutputStream(fd);
synchronized (mGlobalLock) {
- writeToProtoLocked(proto, WindowTraceLogLevel.ALL);
+ dumpDebugLocked(proto, WindowTraceLogLevel.ALL);
}
proto.flush();
return;
@@ -7412,6 +7398,27 @@
public @Nullable KeyInterceptionInfo getKeyInterceptionInfoFromToken(IBinder inputToken) {
return mKeyInterceptionInfoForToken.get(inputToken);
}
+
+ @Override
+ public void setAccessibilityIdToSurfaceMetadata(
+ IBinder windowToken, int accessibilityWindowId) {
+ synchronized (mGlobalLock) {
+ final WindowState state = mWindowMap.get(windowToken);
+ if (state == null) {
+ 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();
+ }
+ }
+ }
}
void registerAppFreezeListener(AppFreezeListener listener) {
@@ -7626,12 +7633,15 @@
// it as if the host window was tapped.
touchedWindow = mEmbeddedWindowController.getHostWindow(touchedToken);
}
- if (touchedWindow == null || !touchedWindow.canReceiveKeys()) {
+
+ if (touchedWindow == null || !touchedWindow.canReceiveKeys(true /* fromUserTouch */)) {
+ // If the window that received the input event cannot receive keys, don't move the
+ // display it's on to the top since that window won't be able to get focus anyway.
return;
}
- handleTaskFocusChange(touchedWindow.getTask());
handleDisplayFocusChange(touchedWindow);
+ handleTaskFocusChange(touchedWindow.getTask());
}
private void handleTaskFocusChange(Task task) {
@@ -7659,12 +7669,6 @@
return;
}
- if (!window.canReceiveKeys()) {
- // If the window that received the input event cannot receive keys, don't move the
- // display it's on to the top since that window won't be able to get focus anyway.
- return;
- }
-
final WindowContainer parent = displayContent.getParent();
if (parent != null && parent.getTopChild() != displayContent) {
parent.positionChildAt(WindowContainer.POSITION_TOP, displayContent,
@@ -7676,7 +7680,8 @@
// to do so because it seems possible to resume activities as part of a larger
// transaction and it's too early to resume based on current order when performing
// updateTopResumedActivityIfNeeded().
- displayContent.mActivityDisplay.ensureActivitiesVisible(null /* starting */,
+ // TODO(display-merge): Remove cast
+ ((ActivityDisplay) displayContent).ensureActivitiesVisible(null /* starting */,
0 /* configChanges */, !PRESERVE_WINDOWS, true /* notifyClients */);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index e169037..ddf8e9b 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -1173,9 +1173,9 @@
pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
if (mListener != null) {
- mListener.writeToProto(proto, fieldId);
+ mListener.dumpDebug(proto, fieldId);
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessListener.java b/services/core/java/com/android/server/wm/WindowProcessListener.java
index 1dade15..870cbb0 100644
--- a/services/core/java/com/android/server/wm/WindowProcessListener.java
+++ b/services/core/java/com/android/server/wm/WindowProcessListener.java
@@ -60,7 +60,7 @@
/** App died :(...oh well */
void appDied();
- void writeToProto(ProtoOutputStream proto, long fieldId);
+ void dumpDebug(ProtoOutputStream proto, long fieldId);
/**
* Sets if the process is currently running a remote animation, which is taken a signal for
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ce26e5f..6a1aa02 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -35,6 +35,7 @@
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
@@ -2162,12 +2163,13 @@
return false;
}
- // Can be an IME target only if:
- // 1. FLAG_NOT_FOCUSABLE is not set
- // 2. FLAG_ALT_FOCUSABLE_IM is not set
- // 3. not a starting window.
- if (!WindowManager.LayoutParams.mayUseInputMethod(mAttrs.flags)
- || mAttrs.type == TYPE_APPLICATION_STARTING) {
+ final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
+ final int type = mAttrs.type;
+
+ // Can only be an IME target if both FLAG_NOT_FOCUSABLE and FLAG_ALT_FOCUSABLE_IM are set or
+ // both are cleared...and not a starting window.
+ if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)
+ && type != TYPE_APPLICATION_STARTING) {
return false;
}
@@ -2616,11 +2618,22 @@
@Override
public boolean canReceiveKeys() {
- return isVisibleOrAdding()
+ return canReceiveKeys(false /* fromUserTouch */);
+ }
+
+ public boolean canReceiveKeys(boolean fromUserTouch) {
+ final boolean canReceiveKeys = isVisibleOrAdding()
&& (mViewVisibility == View.VISIBLE) && !mRemoveOnExit
&& ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0)
&& (mActivityRecord == null || mActivityRecord.windowsAreFocusable())
&& !cantReceiveTouchInput();
+ if (!canReceiveKeys) {
+ return false;
+ }
+ // Do not allow untrusted virtual display to receive keys unless user intentionally
+ // touches the display.
+ return fromUserTouch || getDisplayContent().isOnTop()
+ || !getDisplayContent().isUntrustedVirtualDisplay();
}
@Override
@@ -3598,7 +3611,7 @@
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
boolean isVisible = isVisible();
if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible) {
@@ -3606,19 +3619,19 @@
}
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
+ super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
writeIdentifierToProto(proto, IDENTIFIER);
proto.write(DISPLAY_ID, getDisplayId());
proto.write(STACK_ID, getStackId());
- mAttrs.writeToProto(proto, ATTRIBUTES);
- mGivenContentInsets.writeToProto(proto, GIVEN_CONTENT_INSETS);
- mWindowFrames.writeToProto(proto, WINDOW_FRAMES);
- mAttrs.surfaceInsets.writeToProto(proto, SURFACE_INSETS);
- mSurfacePosition.writeToProto(proto, SURFACE_POSITION);
- mWinAnimator.writeToProto(proto, ANIMATOR);
+ mAttrs.dumpDebug(proto, ATTRIBUTES);
+ mGivenContentInsets.dumpDebug(proto, GIVEN_CONTENT_INSETS);
+ mWindowFrames.dumpDebug(proto, WINDOW_FRAMES);
+ mAttrs.surfaceInsets.dumpDebug(proto, SURFACE_INSETS);
+ mSurfacePosition.dumpDebug(proto, SURFACE_POSITION);
+ mWinAnimator.dumpDebug(proto, ANIMATOR);
proto.write(ANIMATING_EXIT, mAnimatingExit);
for (int i = 0; i < mChildren.size(); i++) {
- mChildren.get(i).writeToProto(proto, CHILD_WINDOWS, logLevel);
+ mChildren.get(i).dumpDebug(proto, CHILD_WINDOWS, logLevel);
}
proto.write(REQUESTED_WIDTH, mRequestedWidth);
proto.write(REQUESTED_HEIGHT, mRequestedHeight);
@@ -5390,10 +5403,10 @@
}
@Override
- public void writeToProtoInner(ProtoOutputStream proto) {
+ public void dumpDebugInner(ProtoOutputStream proto) {
final long token = proto.start(MOVE);
- mFrom.writeToProto(proto, FROM);
- mTo.writeToProto(proto, TO);
+ mFrom.dumpDebug(proto, FROM);
+ mTo.dumpDebug(proto, TO);
proto.write(DURATION_MS, mDuration);
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 94aff7b..c420291 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1405,14 +1405,14 @@
return mWin.isAnimating(TRANSITION | PARENTS);
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- mLastClipRect.writeToProto(proto, LAST_CLIP_RECT);
+ mLastClipRect.dumpDebug(proto, LAST_CLIP_RECT);
if (mSurfaceController != null) {
- mSurfaceController.writeToProto(proto, SURFACE);
+ mSurfaceController.dumpDebug(proto, SURFACE);
}
proto.write(DRAW_STATE, mDrawState);
- mSystemDecorRect.writeToProto(proto, SYSTEM_DECOR_RECT);
+ mSystemDecorRect.dumpDebug(proto, SYSTEM_DECOR_RECT);
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 0b4ea99..5b8015b 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -510,7 +510,7 @@
return mSurfaceH;
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(SHOWN, mSurfaceShown);
proto.write(LAYER, mSurfaceLayer);
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 287d7cd..f81713e 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -258,18 +258,18 @@
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId,
+ public void dumpDebug(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
return;
}
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
+ super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
proto.write(HASH_CODE, System.identityHashCode(this));
for (int i = 0; i < mChildren.size(); i++) {
final WindowState w = mChildren.get(i);
- w.writeToProto(proto, WINDOWS, logLevel);
+ w.dumpDebug(proto, WINDOWS, logLevel);
}
proto.write(WAITING_TO_SHOW, waitingToShow);
proto.write(PAUSED, paused);
diff --git a/services/core/java/com/android/server/wm/WindowTracing.java b/services/core/java/com/android/server/wm/WindowTracing.java
index bb66530..0be90fc 100644
--- a/services/core/java/com/android/server/wm/WindowTracing.java
+++ b/services/core/java/com/android/server/wm/WindowTracing.java
@@ -298,9 +298,9 @@
long tokenInner = os.start(WINDOW_MANAGER_SERVICE);
synchronized (mGlobalLock) {
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "writeToProtoLocked");
+ Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "dumpDebugLocked");
try {
- mService.writeToProtoLocked(os, mLogLevel);
+ mService.dumpDebugLocked(os, mLogLevel);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 612a1e7..dcff5a1 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -338,7 +338,7 @@
if (auto hal = getHal<aidl::IVibrator>()) {
int32_t lengthMs;
sp<AidlVibratorCallback> effectCallback = new AidlVibratorCallback(env, vibration);
- aidl::Effect effectType(static_cast<aidl::Effect>(strength));
+ aidl::Effect effectType(static_cast<aidl::Effect>(effect));
aidl::EffectStrength effectStrength(static_cast<aidl::EffectStrength>(strength));
auto status = hal->call(&aidl::IVibrator::perform, effectType, effectStrength, effectCallback, &lengthMs);
diff --git a/services/core/xsd/platform-compat-config.xsd b/services/core/xsd/platform-compat-config.xsd
index ee39e50..a70568f 100644
--- a/services/core/xsd/platform-compat-config.xsd
+++ b/services/core/xsd/platform-compat-config.xsd
@@ -28,6 +28,7 @@
<xs:attribute type="xs:string" name="name" use="required"/>
<xs:attribute type="xs:boolean" name="disabled"/>
<xs:attribute type="xs:int" name="enableAfterTargetSdk"/>
+ <xs:attribute type="xs:string" name="description"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
diff --git a/services/core/xsd/platform-compat-schema/current.txt b/services/core/xsd/platform-compat-schema/current.txt
index 8456785..3a33f63 100644
--- a/services/core/xsd/platform-compat-schema/current.txt
+++ b/services/core/xsd/platform-compat-schema/current.txt
@@ -3,11 +3,13 @@
public class Change {
ctor public Change();
+ method public String getDescription();
method public boolean getDisabled();
method public int getEnableAfterTargetSdk();
method public long getId();
method public String getName();
method public String getValue();
+ method public void setDescription(String);
method public void setDisabled(boolean);
method public void setEnableAfterTargetSdk(int);
method public void setId(long);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2499ad8..cb599be 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -139,6 +139,8 @@
import android.app.backup.IBackupManager;
import android.app.timedetector.ManualTimeSuggestion;
import android.app.timedetector.TimeDetector;
+import android.app.timezonedetector.ManualTimeZoneSuggestion;
+import android.app.timezonedetector.TimeZoneDetector;
import android.app.trust.TrustManager;
import android.app.usage.UsageStatsManagerInternal;
import android.compat.annotation.ChangeId;
@@ -1962,6 +1964,10 @@
return mContext.getSystemService(TimeDetector.class);
}
+ TimeZoneDetector getTimeZoneDetector() {
+ return mContext.getSystemService(TimeZoneDetector.class);
+ }
+
ConnectivityManager getConnectivityManager() {
return mContext.getSystemService(ConnectivityManager.class);
}
@@ -2748,6 +2754,9 @@
return null;
}
+ // Code for handling failure from getActiveAdminWithPolicyForUidLocked to find an admin
+ // that satisfies the required policy.
+ // Throws a security exception with the right error message.
if (who != null) {
final int userId = UserHandle.getUserId(callingUid);
final DevicePolicyData policy = getUserData(userId);
@@ -2763,6 +2772,10 @@
throw new SecurityException("Admin " + admin.info.getComponent()
+ " does not own the profile");
}
+ if (reqPolicy == DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER) {
+ throw new SecurityException("Admin " + admin.info.getComponent()
+ + " is not the profile owner on organization-owned device");
+ }
if (DA_DISALLOWED_POLICIES.contains(reqPolicy) && !isDeviceOwner && !isProfileOwner) {
throw new SecurityException("Admin " + admin.info.getComponent()
+ " is not a device owner or profile owner, so may not use policy: "
@@ -2869,12 +2882,16 @@
ensureLocked();
final boolean ownsDevice = isDeviceOwner(admin.info.getComponent(), userId);
final boolean ownsProfile = isProfileOwner(admin.info.getComponent(), userId);
+ final boolean ownsProfileOnOrganizationOwnedDevice =
+ isProfileOwnerOfOrganizationOwnedDevice(admin.info.getComponent(), userId);
if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) {
return ownsDevice;
+ } else if (reqPolicy == DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER) {
+ return ownsDevice || ownsProfileOnOrganizationOwnedDevice;
} else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) {
// DO always has the PO power.
- return ownsDevice || ownsProfile;
+ return ownsDevice || ownsProfileOnOrganizationOwnedDevice || ownsProfile;
} else {
boolean allowedToUsePolicy = ownsDevice || ownsProfile
|| !DA_DISALLOWED_POLICIES.contains(reqPolicy)
@@ -5574,6 +5591,13 @@
}
}
+ private void enforceDeviceOwnerOrProfileOwnerOnOrganizationOwnedDevice(ComponentName who) {
+ synchronized (getLockObject()) {
+ getActiveAdminForCallerLocked(
+ who, DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER);
+ }
+ }
+
private void enforceProfileOwnerOfOrganizationOwnedDevice(ActiveAdmin admin) {
if (!isProfileOwnerOfOrganizationOwnedDevice(admin)) {
throw new SecurityException(String.format("Provided admin %s is either not a profile "
@@ -8071,21 +8095,12 @@
return false;
}
- final int adminUserId = admin.getUserHandle().getIdentifier();
+ return isProfileOwnerOfOrganizationOwnedDevice(
+ admin.info.getComponent(), admin.getUserHandle().getIdentifier());
+ }
- if (!isProfileOwner(admin.info.getComponent(), adminUserId)) {
- Slog.w(LOG_TAG, String.format("%s is not profile owner of user %d",
- admin.info.getComponent(), adminUserId));
- return false;
- }
-
- if (!canProfileOwnerAccessDeviceIds(adminUserId)) {
- Slog.w(LOG_TAG, String.format("Profile owner of user %d does not own the device.",
- adminUserId));
- return false;
- }
-
- return true;
+ private boolean isProfileOwnerOfOrganizationOwnedDevice(ComponentName who, int userId) {
+ return isProfileOwner(who, userId) && canProfileOwnerAccessDeviceIds(userId);
}
@Override
@@ -11123,8 +11138,11 @@
if (mInjector.settingsGlobalGetInt(Global.AUTO_TIME_ZONE, 0) == 1) {
return false;
}
+ ManualTimeZoneSuggestion manualTimeZoneSuggestion =
+ TimeZoneDetector.createManualTimeZoneSuggestion(
+ timeZone, "DevicePolicyManagerService: setTimeZone");
mInjector.binderWithCleanCallingIdentity(() ->
- mInjector.getAlarmManager().setTimeZone(timeZone));
+ mInjector.getTimeZoneDetector().suggestManualTimeZone(manualTimeZoneSuggestion));
return true;
}
@@ -12377,7 +12395,7 @@
@Override
public String getWifiMacAddress(ComponentName admin) {
// Make sure caller has DO.
- enforceDeviceOwner(admin);
+ enforceDeviceOwnerOrProfileOwnerOnOrganizationOwnedDevice(admin);
final long ident = mInjector.binderClearCallingIdentity();
try {
diff --git a/services/net/java/android/net/ip/IpClientCallbacks.java b/services/net/java/android/net/ip/IpClientCallbacks.java
index db01ae4..61cd88a 100644
--- a/services/net/java/android/net/ip/IpClientCallbacks.java
+++ b/services/net/java/android/net/ip/IpClientCallbacks.java
@@ -17,8 +17,11 @@
package android.net.ip;
import android.net.DhcpResults;
+import android.net.Layer2PacketParcelable;
import android.net.LinkProperties;
+import java.util.List;
+
/**
* Callbacks for handling IpClient events.
*
@@ -116,4 +119,9 @@
* whenever 464xlat is being started or stopped.
*/
public void setNeighborDiscoveryOffload(boolean enable) {}
+
+ /**
+ * Invoked on starting preconnection process.
+ */
+ public void onPreconnectionStart(List<Layer2PacketParcelable> packets) {}
}
diff --git a/services/net/java/android/net/ip/IpClientManager.java b/services/net/java/android/net/ip/IpClientManager.java
index 1e653cd..4b7ed3c 100644
--- a/services/net/java/android/net/ip/IpClientManager.java
+++ b/services/net/java/android/net/ip/IpClientManager.java
@@ -234,7 +234,7 @@
slot, KeepalivePacketDataUtil.toStableParcelable(pkt));
return true;
} catch (RemoteException e) {
- log("Error adding Keepalive Packet Filter ", e);
+ log("Error adding NAT-T Keepalive Packet Filter ", e);
return false;
} finally {
Binder.restoreCallingIdentity(token);
@@ -272,4 +272,22 @@
Binder.restoreCallingIdentity(token);
}
}
+
+ /**
+ * Notify IpClient that preconnection is complete and that the link is ready for use.
+ * The success parameter indicates whether the packets passed in by 'onPreconnectionStart'
+ * were successfully sent to the network or not.
+ */
+ public boolean notifyPreconnectionComplete(boolean success) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mIpClient.notifyPreconnectionComplete(success);
+ return true;
+ } catch (RemoteException e) {
+ log("Error notifying IpClient Preconnection completed", e);
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
}
diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java
index 714ade1..4d60e62 100644
--- a/services/net/java/android/net/ip/IpClientUtil.java
+++ b/services/net/java/android/net/ip/IpClientUtil.java
@@ -20,12 +20,14 @@
import android.content.Context;
import android.net.DhcpResultsParcelable;
+import android.net.Layer2PacketParcelable;
import android.net.LinkProperties;
import android.net.NetworkStackClient;
import android.os.ConditionVariable;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.List;
/**
@@ -176,6 +178,12 @@
mCb.setNeighborDiscoveryOffload(enable);
}
+ // Invoked on starting preconnection process.
+ @Override
+ public void onPreconnectionStart(List<Layer2PacketParcelable> packets) {
+ mCb.onPreconnectionStart(packets);
+ }
+
@Override
public int getInterfaceVersion() {
return this.VERSION;
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 6c09239..8e6114a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -1053,6 +1053,35 @@
@SuppressWarnings("GuardedBy")
@Test
+ public void testUpdateOomAdj_DoOne_Service_Chain_BoundByFgService_Cycle_2() {
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+ ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+ bindService(app, client, null, 0, mock(IBinder.class));
+ bindService(client, app, null, 0, mock(IBinder.class));
+ ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
+ MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
+ bindService(client2, client, null, 0, mock(IBinder.class));
+ client.setHasForegroundServices(true, 0);
+ ArrayList<ProcessRecord> lru = sService.mProcessList.mLruProcesses;
+ lru.clear();
+ lru.add(app);
+ lru.add(client);
+ lru.add(client2);
+ sService.mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
+ sService.mOomAdjuster.updateOomAdjLocked(app, true, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+ assertProcStates(client, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+ assertProcStates(client2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_DoOne_Service_Chain_BoundByFgService_Cycle_Branch() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index fb42507..3a07a69 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -40,6 +40,7 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+ <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
index 37f5b87..3352177 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
@@ -16,18 +16,39 @@
package com.android.server.accessibility;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.accessibilityservice.AccessibilityService;
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
+import android.app.RemoteAction;
import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.drawable.Icon;
import android.os.Handler;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+
+import androidx.test.InstrumentationRegistry;
import com.android.internal.util.ScreenshotHelper;
+import com.android.server.LocalServices;
+import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.WindowManagerInternal;
import org.junit.Before;
@@ -35,55 +56,290 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
/**
* Tests for SystemActionPerformer
*/
public class SystemActionPerformerTest {
- SystemActionPerformer mSystemActionPerformer;
+ private static final int LATCH_TIMEOUT_MS = 500;
+ private static final int LEGACY_SYSTEM_ACTION_COUNT = 9;
+ private static final int NEW_ACTION_ID = 20;
+ private static final String LABEL_1 = "label1";
+ private static final String LABEL_2 = "label2";
+ private static final String INTENT_ACTION1 = "TESTACTION1";
+ private static final String INTENT_ACTION2 = "TESTACTION2";
+ private static final String DESCRIPTION1 = "description1";
+ private static final String DESCRIPTION2 = "description2";
+ private static final PendingIntent TEST_PENDING_INTENT_1 = PendingIntent.getBroadcast(
+ InstrumentationRegistry.getTargetContext(), 0, new Intent(INTENT_ACTION1), 0);
+ private static final RemoteAction NEW_TEST_ACTION_1 = new RemoteAction(
+ Icon.createWithContentUri("content://test"),
+ LABEL_1,
+ DESCRIPTION1,
+ TEST_PENDING_INTENT_1);
+ private static final PendingIntent TEST_PENDING_INTENT_2 = PendingIntent.getBroadcast(
+ InstrumentationRegistry.getTargetContext(), 0, new Intent(INTENT_ACTION2), 0);
+ private static final RemoteAction NEW_TEST_ACTION_2 = new RemoteAction(
+ Icon.createWithContentUri("content://test"),
+ LABEL_2,
+ DESCRIPTION2,
+ TEST_PENDING_INTENT_2);
- @Mock Context mMockContext;
- @Mock WindowManagerInternal mMockWindowManagerInternal;
- @Mock StatusBarManager mMockStatusBarManager;
- @Mock ScreenshotHelper mMockScreenshotHelper;
+ private static final AccessibilityAction NEW_ACCESSIBILITY_ACTION =
+ new AccessibilityAction(NEW_ACTION_ID, LABEL_1);
+ private static final AccessibilityAction LEGACY_NOTIFICATIONS_ACCESSIBILITY_ACTION =
+ new AccessibilityAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS, LABEL_1);
+ private static final AccessibilityAction LEGACY_HOME_ACCESSIBILITY_ACTION =
+ new AccessibilityAction(AccessibilityService.GLOBAL_ACTION_HOME, LABEL_2);
+
+ private SystemActionPerformer mSystemActionPerformer;
+
+ @Mock private Context mMockContext;
+ @Mock private StatusBarManagerInternal mMockStatusBarManagerInternal;
+ @Mock private WindowManagerInternal mMockWindowManagerInternal;
+ @Mock private StatusBarManager mMockStatusBarManager;
+ @Mock private ScreenshotHelper mMockScreenshotHelper;
+ @Mock private SystemActionPerformer.SystemActionsChangedListener mMockListener;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
+ LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
+ LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal);
+ }
- when(mMockContext.getSystemService(android.app.Service.STATUS_BAR_SERVICE))
- .thenReturn(mMockStatusBarManager);
+ private void setupWithMockContext() {
+ doReturn(mMockStatusBarManager).when(
+ mMockContext).getSystemService(android.app.Service.STATUS_BAR_SERVICE);
+ doReturn(InstrumentationRegistry.getContext().getResources()).when(
+ mMockContext).getResources();
+ mSystemActionPerformer = new SystemActionPerformer(
+ mMockContext,
+ mMockWindowManagerInternal,
+ () -> mMockScreenshotHelper,
+ mMockListener);
+ }
- mSystemActionPerformer =
- new SystemActionPerformer(mMockContext, mMockWindowManagerInternal,
- () -> mMockScreenshotHelper);
+ private void setupWithRealContext() {
+ mSystemActionPerformer = new SystemActionPerformer(
+ InstrumentationRegistry.getContext(),
+ mMockWindowManagerInternal,
+ () -> mMockScreenshotHelper,
+ mMockListener);
+ }
+
+ // We need below two help functions because AccessbilityAction.equals function only compares
+ // action ids. To verify the test result here, we are also looking at action labels.
+ private void assertHasLegacyAccessibilityAction(
+ List<AccessibilityAction> actions, AccessibilityAction action) {
+ boolean foundAction = false;
+ for (AccessibilityAction a : actions) {
+ if ((a.getId() == action.getId()) && (a.getLabel().equals(action.getLabel()))) {
+ foundAction = true;
+ break;
+ }
+ }
+ assertTrue(foundAction);
+ }
+
+ private void assertHasNoLegacyAccessibilityAction(
+ List<AccessibilityAction> actions, AccessibilityAction action) {
+ boolean foundAction = false;
+ for (AccessibilityAction a : actions) {
+ if ((a.getId() == action.getId()) && (a.getLabel().equals(action.getLabel()))) {
+ foundAction = true;
+ break;
+ }
+ }
+ assertFalse(foundAction);
}
@Test
- public void testNotifications_expandsNotificationPanel() {
+ public void testRegisterSystemAction_addedIntoAvailableSystemActions() {
+ setupWithRealContext();
+ // Before any new system action is registered, getSystemActions returns all legacy actions
+ List<AccessibilityAction> actions = mSystemActionPerformer.getSystemActions();
+ assertEquals(LEGACY_SYSTEM_ACTION_COUNT, actions.size());
+ // Register a new system action
+ mSystemActionPerformer.registerSystemAction(NEW_ACTION_ID, NEW_TEST_ACTION_1);
+ actions = mSystemActionPerformer.getSystemActions();
+ assertEquals(LEGACY_SYSTEM_ACTION_COUNT + 1, actions.size());
+ assertThat(actions, hasItem(NEW_ACCESSIBILITY_ACTION));
+ }
+
+ @Test
+ public void testRegisterSystemAction_overrideLegacyAction() {
+ setupWithRealContext();
+ // Before any new system action is registered, getSystemActions returns all legacy actions
+ List<AccessibilityAction> actions = mSystemActionPerformer.getSystemActions();
+ assertEquals(LEGACY_SYSTEM_ACTION_COUNT, actions.size());
+ // Overriding a legacy system action using legacy notification action id
+ mSystemActionPerformer.registerSystemAction(
+ AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS, NEW_TEST_ACTION_1);
+ actions = mSystemActionPerformer.getSystemActions();
+ assertEquals(LEGACY_SYSTEM_ACTION_COUNT, actions.size());
+ assertHasLegacyAccessibilityAction(actions, LEGACY_NOTIFICATIONS_ACCESSIBILITY_ACTION);
+ }
+
+ @Test
+ public void testUnregisterSystemAction_removeFromAvailableSystemActions() {
+ setupWithRealContext();
+ // Before any new system action is registered, getSystemActions returns all legacy actions
+ List<AccessibilityAction> actions = mSystemActionPerformer.getSystemActions();
+ assertEquals(LEGACY_SYSTEM_ACTION_COUNT, actions.size());
+ // Register a new system action
+ mSystemActionPerformer.registerSystemAction(NEW_ACTION_ID, NEW_TEST_ACTION_1);
+ actions = mSystemActionPerformer.getSystemActions();
+ assertEquals(LEGACY_SYSTEM_ACTION_COUNT + 1, actions.size());
+
+ mSystemActionPerformer.unregisterSystemAction(NEW_ACTION_ID);
+ actions = mSystemActionPerformer.getSystemActions();
+ assertEquals(LEGACY_SYSTEM_ACTION_COUNT, actions.size());
+ assertThat(actions, is(not(hasItem(NEW_ACCESSIBILITY_ACTION))));
+ }
+
+ @Test
+ public void testUnregisterSystemAction_removeOverrideForLegacyAction() {
+ setupWithRealContext();
+
+ // Overriding a legacy system action
+ mSystemActionPerformer.registerSystemAction(
+ AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS, NEW_TEST_ACTION_1);
+ List<AccessibilityAction> actions = mSystemActionPerformer.getSystemActions();
+ assertEquals(LEGACY_SYSTEM_ACTION_COUNT, actions.size());
+ assertHasLegacyAccessibilityAction(actions, LEGACY_NOTIFICATIONS_ACCESSIBILITY_ACTION);
+
+ // Remove the overriding action using legacy action id
+ mSystemActionPerformer.unregisterSystemAction(
+ AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS);
+ actions = mSystemActionPerformer.getSystemActions();
+ assertEquals(LEGACY_SYSTEM_ACTION_COUNT, actions.size());
+ assertHasNoLegacyAccessibilityAction(actions, LEGACY_NOTIFICATIONS_ACCESSIBILITY_ACTION);
+ }
+
+ @Test
+ public void testPerformSystemActionNewAction() throws CanceledException {
+ setupWithRealContext();
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ mSystemActionPerformer.registerSystemAction(NEW_ACTION_ID, NEW_TEST_ACTION_1);
+ TestBroadcastReceiver br = new TestBroadcastReceiver(latch);
+ br.register(InstrumentationRegistry.getTargetContext());
+ mSystemActionPerformer.performSystemAction(NEW_ACTION_ID);
+ try {
+ latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ fail("RemoteAction should be triggered.");
+ } finally {
+ br.unregister(InstrumentationRegistry.getTargetContext());
+ }
+ }
+
+ @Test
+ public void testPerformSystemActionOverrideLegacyActionUsingLegacyActionId()
+ throws CanceledException {
+ setupWithRealContext();
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ mSystemActionPerformer.registerSystemAction(
+ AccessibilityService.GLOBAL_ACTION_RECENTS, NEW_TEST_ACTION_1);
+ TestBroadcastReceiver br = new TestBroadcastReceiver(latch);
+ br.register(InstrumentationRegistry.getTargetContext());
+ mSystemActionPerformer.performSystemAction(AccessibilityService.GLOBAL_ACTION_RECENTS);
+ try {
+ latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ fail("RemoteAction should be triggered.");
+ } finally {
+ br.unregister(InstrumentationRegistry.getTargetContext());
+ }
+ verify(mMockStatusBarManagerInternal, never()).toggleRecentApps();
+ // Now revert to legacy action
+ mSystemActionPerformer.unregisterSystemAction(AccessibilityService.GLOBAL_ACTION_RECENTS);
+ mSystemActionPerformer.performSystemAction(AccessibilityService.GLOBAL_ACTION_RECENTS);
+ verify(mMockStatusBarManagerInternal).toggleRecentApps();
+ }
+
+ @Test
+ public void testNotifications_expandsNotificationPanel_legacy() {
+ setupWithMockContext();
mSystemActionPerformer
.performSystemAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS);
verify(mMockStatusBarManager).expandNotificationsPanel();
}
@Test
- public void testQuickSettings_requestsQuickSettingsPanel() {
+ public void testQuickSettings_requestsQuickSettingsPanel_legacy() {
+ setupWithMockContext();
mSystemActionPerformer
.performSystemAction(AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS);
verify(mMockStatusBarManager).expandSettingsPanel();
}
@Test
- public void testPowerDialog_requestsFromWindowManager() {
+ public void testRecentApps_legacy() {
+ setupWithRealContext();
+ mSystemActionPerformer.performSystemAction(AccessibilityService.GLOBAL_ACTION_RECENTS);
+ verify(mMockStatusBarManagerInternal).toggleRecentApps();
+ }
+
+ @Test
+ public void testPowerDialog_requestsFromWindowManager_legacy() {
+ setupWithMockContext();
mSystemActionPerformer.performSystemAction(AccessibilityService.GLOBAL_ACTION_POWER_DIALOG);
verify(mMockWindowManagerInternal).showGlobalActions();
}
@Test
- public void testScreenshot_requestsFromScreenshotHelper() {
+ public void testToggleSplitScreen_legacy() {
+ setupWithRealContext();
+ mSystemActionPerformer.performSystemAction(
+ AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN);
+ verify(mMockStatusBarManagerInternal).toggleSplitScreen();
+ }
+
+ @Test
+ public void testScreenshot_requestsFromScreenshotHelper_legacy() {
+ setupWithMockContext();
mSystemActionPerformer.performSystemAction(
AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT);
verify(mMockScreenshotHelper).takeScreenshot(
eq(android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN), anyBoolean(),
anyBoolean(), any(Handler.class), any());
}
+
+ // PendingIntent is a final class and cannot be mocked. So we are using this
+ // Broadcast receiver to verify the registered remote action is called correctly.
+ private static final class TestBroadcastReceiver extends BroadcastReceiver {
+ private CountDownLatch mLatch;
+ private boolean mRegistered;
+ private final IntentFilter mFilter;
+
+ TestBroadcastReceiver(CountDownLatch latch) {
+ mLatch = latch;
+ mRegistered = false;
+ mFilter = new IntentFilter(INTENT_ACTION1);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mLatch.countDown();
+ }
+
+ void register(Context context) {
+ if (!mRegistered) {
+ context.registerReceiver(this, mFilter);
+ mRegistered = true;
+ }
+ }
+
+ void unregister(Context context) {
+ if (mRegistered) {
+ context.unregisterReceiver(this);
+ }
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/impl/FakeIcingTest.java b/services/tests/servicestests/src/com/android/server/appsearch/impl/FakeIcingTest.java
index adef02e..6f2de7f 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/impl/FakeIcingTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/impl/FakeIcingTest.java
@@ -21,6 +21,7 @@
import com.google.android.icing.proto.DocumentProto;
import com.google.android.icing.proto.PropertyProto;
+import com.google.android.icing.proto.SearchResultProto;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -115,8 +116,9 @@
private static List<String> queryGetUris(FakeIcing icing, String term) {
List<String> uris = new ArrayList<>();
- for (DocumentProto result : icing.query(term)) {
- uris.add(result.getUri());
+ SearchResultProto results = icing.query(term);
+ for (SearchResultProto.ResultProto result : results.getResultsList()) {
+ uris.add(result.getDocument().getUri());
}
return uris;
}
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
index f8c87fc..7267976 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
@@ -73,36 +73,36 @@
@Test
public void testDisabledChangeDisabled() {
CompatConfig pc = new CompatConfig();
- pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true));
+ pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true, ""));
assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 1))).isFalse();
}
@Test
public void testTargetSdkChangeDisabled() {
CompatConfig pc = new CompatConfig();
- pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, false));
+ pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, false, null));
assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isFalse();
}
@Test
public void testTargetSdkChangeEnabled() {
CompatConfig pc = new CompatConfig();
- pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, false));
+ pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, false, ""));
assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 3))).isTrue();
}
@Test
public void testDisabledOverrideTargetSdkChange() {
CompatConfig pc = new CompatConfig();
- pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, true));
+ pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, true, null));
assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 3))).isFalse();
}
@Test
public void testGetDisabledChanges() {
CompatConfig pc = new CompatConfig();
- pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true));
- pc.addChange(new CompatChange(2345L, "OTHER_CHANGE", -1, false));
+ pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true, null));
+ pc.addChange(new CompatChange(2345L, "OTHER_CHANGE", -1, false, null));
assertThat(pc.getDisabledChanges(
makeAppInfo("com.some.package", 2))).asList().containsExactly(1234L);
}
@@ -110,9 +110,9 @@
@Test
public void testGetDisabledChangesSorted() {
CompatConfig pc = new CompatConfig();
- pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, true));
- pc.addChange(new CompatChange(123L, "OTHER_CHANGE", 2, true));
- pc.addChange(new CompatChange(12L, "THIRD_CHANGE", 2, true));
+ pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, true, null));
+ pc.addChange(new CompatChange(123L, "OTHER_CHANGE", 2, true, null));
+ pc.addChange(new CompatChange(12L, "THIRD_CHANGE", 2, true, null));
assertThat(pc.getDisabledChanges(
makeAppInfo("com.some.package", 2))).asList().containsExactly(12L, 123L, 1234L);
}
@@ -120,7 +120,7 @@
@Test
public void testPackageOverrideEnabled() {
CompatConfig pc = new CompatConfig();
- pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true)); // disabled
+ pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true, null)); // disabled
pc.addOverride(1234L, "com.some.package", true);
assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isTrue();
assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.other.package", 2))).isFalse();
@@ -129,7 +129,7 @@
@Test
public void testPackageOverrideDisabled() {
CompatConfig pc = new CompatConfig();
- pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false));
+ pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false, null));
pc.addOverride(1234L, "com.some.package", false);
assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isFalse();
assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.other.package", 2))).isTrue();
@@ -152,7 +152,7 @@
@Test
public void testRemovePackageOverride() {
CompatConfig pc = new CompatConfig();
- pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false));
+ pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false, null));
pc.addOverride(1234L, "com.some.package", false);
pc.removeOverride(1234L, "com.some.package");
assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isTrue();
@@ -161,8 +161,8 @@
@Test
public void testLookupChangeId() {
CompatConfig pc = new CompatConfig();
- pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false));
- pc.addChange(new CompatChange(2345L, "ANOTHER_CHANGE", -1, false));
+ pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false, null));
+ pc.addChange(new CompatChange(2345L, "ANOTHER_CHANGE", -1, false, null));
assertThat(pc.lookupChangeId("MY_CHANGE")).isEqualTo(1234L);
}
@@ -174,8 +174,9 @@
@Test
public void testReadConfig() {
- Change[] changes = {new Change(1234L, "MY_CHANGE1", false, 2), new Change(1235L,
- "MY_CHANGE2", true, null), new Change(1236L, "MY_CHANGE3", false, null)};
+ Change[] changes = {new Change(1234L, "MY_CHANGE1", false, 2, null), new Change(1235L,
+ "MY_CHANGE2", true, null, "description"), new Change(1236L, "MY_CHANGE3", false,
+ null, "")};
File dir = createTempDir();
writeChangesToFile(changes, new File(dir.getPath() + "/platform_compat_config.xml"));
@@ -191,9 +192,9 @@
@Test
public void testReadConfigMultipleFiles() {
- Change[] changes1 = {new Change(1234L, "MY_CHANGE1", false, 2)};
- Change[] changes2 = {new Change(1235L, "MY_CHANGE2", true, null), new Change(1236L,
- "MY_CHANGE3", false, null)};
+ Change[] changes1 = {new Change(1234L, "MY_CHANGE1", false, 2, null)};
+ Change[] changes2 = {new Change(1235L, "MY_CHANGE2", true, null, ""), new Change(1236L,
+ "MY_CHANGE3", false, null, null)};
File dir = createTempDir();
writeChangesToFile(changes1,
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 f86bacf..ac555fd 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -23,6 +23,7 @@
import android.app.PendingIntent;
import android.app.backup.IBackupManager;
import android.app.timedetector.TimeDetector;
+import android.app.timezonedetector.TimeZoneDetector;
import android.app.usage.UsageStatsManagerInternal;
import android.content.Context;
import android.content.Intent;
@@ -235,6 +236,11 @@
}
@Override
+ TimeZoneDetector getTimeZoneDetector() {
+ return services.timeZoneDetector;
+ }
+
+ @Override
LockPatternUtils newLockPatternUtils() {
return services.lockPatternUtils;
}
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 0590020..06b8716 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -64,6 +64,8 @@
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.PasswordMetrics;
import android.app.timedetector.ManualTimeSuggestion;
+import android.app.timezonedetector.ManualTimeZoneSuggestion;
+import android.app.timezonedetector.TimeZoneDetector;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Intent;
@@ -138,6 +140,8 @@
permission.MANAGE_USERS, permission.INTERACT_ACROSS_USERS_FULL);
public static final String NOT_DEVICE_OWNER_MSG = "does not own the device";
public static final String NOT_PROFILE_OWNER_MSG = "does not own the profile";
+ public static final String NOT_ORG_OWNED_PROFILE_OWNER_MSG =
+ "not the profile owner on organization-owned device";
public static final String ONGOING_CALL_MSG = "ongoing call on the device";
// TODO replace all instances of this with explicit {@link #mServiceContext}.
@@ -2114,12 +2118,14 @@
assertTrue(dpm.isAdminActive(admin1));
// Test 2. Caller has DA, but not DO.
- assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG,
+ assertExpectException(SecurityException.class,
+ /* messageRegex= */ NOT_ORG_OWNED_PROFILE_OWNER_MSG,
() -> dpm.getWifiMacAddress(admin1));
// Test 3. Caller has PO, but not DO.
assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
- assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG,
+ assertExpectException(SecurityException.class,
+ /* messageRegex= */ NOT_ORG_OWNED_PROFILE_OWNER_MSG,
() -> dpm.getWifiMacAddress(admin1));
// Remove PO.
@@ -2141,6 +2147,15 @@
assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1));
}
+ public void testGetMacAddressByOrgOwnedPO() throws Exception {
+ setupProfileOwner();
+ configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+
+ final String[] macAddresses = new String[]{"11:22:33:44:55:66"};
+ when(getServices().wifiManager.getFactoryMacAddresses()).thenReturn(macAddresses);
+ assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1));
+ }
+
public void testReboot() throws Exception {
mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
@@ -3694,7 +3709,9 @@
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
setupDeviceOwner();
dpm.setTimeZone(admin1, "Asia/Shanghai");
- verify(getServices().alarmManager).setTimeZone("Asia/Shanghai");
+ ManualTimeZoneSuggestion suggestion =
+ TimeZoneDetector.createManualTimeZoneSuggestion("Asia/Shanghai", "Test debug info");
+ verify(getServices().timeZoneDetector).suggestManualTimeZone(suggestion);
}
public void testSetTimeZoneFailWithPO() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index c927364..6a0d926 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -32,6 +32,7 @@
import android.app.NotificationManager;
import android.app.backup.IBackupManager;
import android.app.timedetector.TimeDetector;
+import android.app.timezonedetector.TimeZoneDetector;
import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
@@ -113,6 +114,7 @@
public final AccountManager accountManager;
public final AlarmManager alarmManager;
public final TimeDetector timeDetector;
+ public final TimeZoneDetector timeZoneDetector;
public final KeyChain.KeyChainConnection keyChainConnection;
/** Note this is a partial mock, not a real mock. */
public final PackageManager packageManager;
@@ -155,6 +157,7 @@
accountManager = mock(AccountManager.class);
alarmManager = mock(AlarmManager.class);
timeDetector = mock(TimeDetector.class);
+ timeZoneDetector = mock(TimeZoneDetector.class);
keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS);
// Package manager is huge, so we use a partial mock instead.
diff --git a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java
new file mode 100644
index 0000000..88b6d70
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java
@@ -0,0 +1,628 @@
+/*
+ * 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.server.integrity.parser;
+
+import static com.android.server.integrity.model.ComponentBitSize.ATOMIC_FORMULA_START;
+import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_END;
+import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_START;
+import static com.android.server.integrity.model.ComponentBitSize.CONNECTOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.DEFAULT_FORMAT_VERSION;
+import static com.android.server.integrity.model.ComponentBitSize.EFFECT_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.FORMAT_VERSION_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.KEY_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS;
+import static com.android.server.integrity.utils.TestUtils.getBits;
+import static com.android.server.integrity.utils.TestUtils.getBytes;
+import static com.android.server.integrity.utils.TestUtils.getValueBits;
+import static com.android.server.testutils.TestUtils.assertExpectException;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.integrity.AtomicFormula;
+import android.content.integrity.CompoundFormula;
+import android.content.integrity.Rule;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public class RuleBinaryParserTest {
+
+ private static final String COMPOUND_FORMULA_START_BITS =
+ getBits(COMPOUND_FORMULA_START, SEPARATOR_BITS);
+ private static final String COMPOUND_FORMULA_END_BITS =
+ getBits(COMPOUND_FORMULA_END, SEPARATOR_BITS);
+ private static final String ATOMIC_FORMULA_START_BITS =
+ getBits(ATOMIC_FORMULA_START, SEPARATOR_BITS);
+ private static final int INVALID_FORMULA_SEPARATOR_VALUE = 3;
+ private static final String INVALID_FORMULA_SEPARATOR_BITS =
+ getBits(INVALID_FORMULA_SEPARATOR_VALUE, SEPARATOR_BITS);
+
+ private static final String NOT = getBits(CompoundFormula.NOT, CONNECTOR_BITS);
+ private static final String AND = getBits(CompoundFormula.AND, CONNECTOR_BITS);
+ private static final String OR = getBits(CompoundFormula.OR, CONNECTOR_BITS);
+ private static final int INVALID_CONNECTOR_VALUE = 3;
+ private static final String INVALID_CONNECTOR =
+ getBits(INVALID_CONNECTOR_VALUE, CONNECTOR_BITS);
+
+ private static final String PACKAGE_NAME = getBits(AtomicFormula.PACKAGE_NAME, KEY_BITS);
+ private static final String APP_CERTIFICATE = getBits(AtomicFormula.APP_CERTIFICATE, KEY_BITS);
+ private static final String VERSION_CODE = getBits(AtomicFormula.VERSION_CODE, KEY_BITS);
+ private static final String PRE_INSTALLED = getBits(AtomicFormula.PRE_INSTALLED, KEY_BITS);
+ private static final int INVALID_KEY_VALUE = 6;
+ private static final String INVALID_KEY = getBits(INVALID_KEY_VALUE, KEY_BITS);
+
+ private static final String EQ = getBits(AtomicFormula.EQ, OPERATOR_BITS);
+ private static final int INVALID_OPERATOR_VALUE = 5;
+ private static final String INVALID_OPERATOR = getBits(INVALID_OPERATOR_VALUE, OPERATOR_BITS);
+
+ private static final String IS_NOT_HASHED = "0";
+
+ private static final String DENY = getBits(Rule.DENY, EFFECT_BITS);
+ private static final int INVALID_EFFECT_VALUE = 5;
+ private static final String INVALID_EFFECT = getBits(INVALID_EFFECT_VALUE, EFFECT_BITS);
+
+ private static final String START_BIT = "1";
+ private static final String END_BIT = "1";
+ private static final String INVALID_MARKER_BIT = "0";
+
+ private static final byte[] DEFAULT_FORMAT_VERSION_BYTES =
+ getBytes(getBits(DEFAULT_FORMAT_VERSION, FORMAT_VERSION_BITS));
+
+ @Test
+ public void testBinaryStream_validCompoundFormula() throws Exception {
+ String packageName = "com.test.app";
+ String ruleBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + NOT
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+ InputStream inputStream = new ByteArrayInputStream(rule.array());
+ Rule expectedRule =
+ new Rule(
+ new CompoundFormula(
+ CompoundFormula.NOT,
+ Collections.singletonList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+
+ List<Rule> rules = binaryParser.parse(inputStream);
+
+ assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
+ }
+
+ @Test
+ public void testBinaryString_validCompoundFormula_notConnector() throws Exception {
+ String packageName = "com.test.app";
+ String ruleBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + NOT
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+ Rule expectedRule =
+ new Rule(
+ new CompoundFormula(
+ CompoundFormula.NOT,
+ Collections.singletonList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+
+ List<Rule> rules = binaryParser.parse(rule.array());
+
+ assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
+ }
+
+ @Test
+ public void testBinaryString_validCompoundFormula_andConnector() throws Exception {
+ String packageName = "com.test.app";
+ String appCertificate = "test_cert";
+ String ruleBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + AND
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + ATOMIC_FORMULA_START_BITS
+ + APP_CERTIFICATE
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(appCertificate.length(), VALUE_SIZE_BITS)
+ + getValueBits(appCertificate)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+ Rule expectedRule =
+ new Rule(
+ new CompoundFormula(
+ CompoundFormula.AND,
+ Arrays.asList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false),
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.APP_CERTIFICATE,
+ appCertificate,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+ List<Rule> rules = binaryParser.parse(rule.array());
+
+ assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
+ }
+
+ @Test
+ public void testBinaryString_validCompoundFormula_orConnector() throws Exception {
+ String packageName = "com.test.app";
+ String appCertificate = "test_cert";
+ String ruleBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + OR
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + ATOMIC_FORMULA_START_BITS
+ + APP_CERTIFICATE
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(appCertificate.length(), VALUE_SIZE_BITS)
+ + getValueBits(appCertificate)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+ Rule expectedRule =
+ new Rule(
+ new CompoundFormula(
+ CompoundFormula.OR,
+ Arrays.asList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false),
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.APP_CERTIFICATE,
+ appCertificate,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+
+ List<Rule> rules = binaryParser.parse(rule.array());
+
+ assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
+ }
+
+ @Test
+ public void testBinaryString_validAtomicFormula_stringValue() throws Exception {
+ String packageName = "com.test.app";
+ String ruleBits =
+ START_BIT
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+ Rule expectedRule =
+ new Rule(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false),
+ Rule.DENY);
+
+ List<Rule> rules = binaryParser.parse(rule.array());
+
+ assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
+ }
+
+ @Test
+ public void testBinaryString_validAtomicFormula_integerValue() throws Exception {
+ String versionCode = "1";
+ String ruleBits =
+ START_BIT
+ + ATOMIC_FORMULA_START_BITS
+ + VERSION_CODE
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(versionCode.length(), VALUE_SIZE_BITS)
+ + getValueBits(versionCode)
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+ Rule expectedRule =
+ new Rule(
+ new AtomicFormula.IntAtomicFormula(
+ AtomicFormula.VERSION_CODE, AtomicFormula.EQ, 1),
+ Rule.DENY);
+
+ List<Rule> rules = binaryParser.parse(rule.array());
+
+ assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
+ }
+
+ @Test
+ public void testBinaryString_validAtomicFormula_booleanValue() throws Exception {
+ String isPreInstalled = "1";
+ String ruleBits =
+ START_BIT
+ + ATOMIC_FORMULA_START_BITS
+ + PRE_INSTALLED
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(isPreInstalled.length(), VALUE_SIZE_BITS)
+ + getValueBits(isPreInstalled)
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+ Rule expectedRule =
+ new Rule(
+ new AtomicFormula.BooleanAtomicFormula(AtomicFormula.PRE_INSTALLED, true),
+ Rule.DENY);
+
+ List<Rule> rules = binaryParser.parse(rule.array());
+
+ assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
+ }
+
+ @Test
+ public void testBinaryString_invalidAtomicFormula() throws Exception {
+ String versionCode = "test";
+ String ruleBits =
+ START_BIT
+ + ATOMIC_FORMULA_START_BITS
+ + VERSION_CODE
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(versionCode.length(), VALUE_SIZE_BITS)
+ + getValueBits(versionCode)
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+
+ assertExpectException(
+ RuleParseException.class,
+ /* expectedExceptionMessageRegex */ "For input string:",
+ () -> binaryParser.parse(rule.array()));
+ }
+
+ @Test
+ public void testBinaryString_withNoRuleList() throws RuleParseException {
+ ByteBuffer rule = ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ RuleParser binaryParser = new RuleBinaryParser();
+
+ List<Rule> rules = binaryParser.parse(rule.array());
+
+ assertThat(rules).isEmpty();
+ }
+
+ @Test
+ public void testBinaryString_withEmptyRule() throws RuleParseException {
+ String ruleBits = START_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+
+ assertExpectException(
+ RuleParseException.class,
+ /* expectedExceptionMessageRegex */ "Invalid byte index",
+ () -> binaryParser.parse(rule.array()));
+ }
+
+ @Test
+ public void testBinaryString_invalidCompoundFormula_invalidNumberOfFormulas() throws Exception {
+ String packageName = "com.test.app";
+ String appCertificate = "test_cert";
+ String ruleBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + NOT
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + ATOMIC_FORMULA_START_BITS
+ + APP_CERTIFICATE
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(appCertificate.length(), VALUE_SIZE_BITS)
+ + getValueBits(appCertificate)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+
+ assertExpectException(
+ RuleParseException.class,
+ /* expectedExceptionMessageRegex */ "Connector NOT must have 1 formula only",
+ () -> binaryParser.parse(rule.array()));
+ }
+
+ @Test
+ public void testBinaryString_invalidRule_invalidOperator() throws Exception {
+ String versionCode = "1";
+ String ruleBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + NOT
+ + ATOMIC_FORMULA_START_BITS
+ + VERSION_CODE
+ + INVALID_OPERATOR
+ + IS_NOT_HASHED
+ + getBits(versionCode.length(), VALUE_SIZE_BITS)
+ + getValueBits(versionCode)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+
+ assertExpectException(
+ RuleParseException.class,
+ /* expectedExceptionMessageRegex */ String.format(
+ "Unknown operator: %d", INVALID_OPERATOR_VALUE),
+ () -> binaryParser.parse(rule.array()));
+ }
+
+ @Test
+ public void testBinaryString_invalidRule_invalidEffect() throws Exception {
+ String packageName = "com.test.app";
+ String ruleBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + NOT
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + COMPOUND_FORMULA_END_BITS
+ + INVALID_EFFECT
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+
+ assertExpectException(
+ RuleParseException.class,
+ /* expectedExceptionMessageRegex */ String.format(
+ "Unknown effect: %d", INVALID_EFFECT_VALUE),
+ () -> binaryParser.parse(rule.array()));
+ }
+
+ @Test
+ public void testBinaryString_invalidRule_invalidConnector() throws Exception {
+ String packageName = "com.test.app";
+ String ruleBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + INVALID_CONNECTOR
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+
+ assertExpectException(
+ RuleParseException.class,
+ /* expectedExceptionMessageRegex */ String.format(
+ "Unknown connector: %d", INVALID_CONNECTOR_VALUE),
+ () -> binaryParser.parse(rule.array()));
+ }
+
+ @Test
+ public void testBinaryString_invalidRule_invalidKey() throws Exception {
+ String packageName = "com.test.app";
+ String ruleBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + NOT
+ + ATOMIC_FORMULA_START_BITS
+ + INVALID_KEY
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+
+ assertExpectException(
+ RuleParseException.class,
+ /* expectedExceptionMessageRegex */ String.format(
+ "Unknown key: %d", INVALID_KEY_VALUE),
+ () -> binaryParser.parse(rule.array()));
+ }
+
+ @Test
+ public void testBinaryString_invalidRule_invalidSeparator() throws Exception {
+ String packageName = "com.test.app";
+ String ruleBits =
+ START_BIT
+ + INVALID_FORMULA_SEPARATOR_BITS
+ + NOT
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+
+ assertExpectException(
+ RuleParseException.class,
+ /* expectedExceptionMessageRegex */ String.format(
+ "Unknown formula separator: %d", INVALID_FORMULA_SEPARATOR_VALUE),
+ () -> binaryParser.parse(rule.array()));
+ }
+
+ @Test
+ public void testBinaryString_invalidRule_invalidEndMarker() throws Exception {
+ String packageName = "com.test.app";
+ String ruleBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + NOT
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + INVALID_MARKER_BIT;
+ byte[] ruleBytes = getBytes(ruleBits);
+ ByteBuffer rule =
+ ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+ rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+ rule.put(ruleBytes);
+ RuleParser binaryParser = new RuleBinaryParser();
+
+ assertExpectException(
+ RuleParseException.class,
+ /* expectedExceptionMessageRegex */ "A rule must end with a '1' bit",
+ () -> binaryParser.parse(rule.array()));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleBinarySerializerTest.java b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleBinarySerializerTest.java
new file mode 100644
index 0000000..901277d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleBinarySerializerTest.java
@@ -0,0 +1,444 @@
+/*
+ * 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.server.integrity.serializer;
+
+import static com.android.server.integrity.model.ComponentBitSize.ATOMIC_FORMULA_START;
+import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_END;
+import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_START;
+import static com.android.server.integrity.model.ComponentBitSize.CONNECTOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.DEFAULT_FORMAT_VERSION;
+import static com.android.server.integrity.model.ComponentBitSize.EFFECT_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.FORMAT_VERSION_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.KEY_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS;
+import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS;
+import static com.android.server.integrity.utils.TestUtils.getBits;
+import static com.android.server.integrity.utils.TestUtils.getBytes;
+import static com.android.server.integrity.utils.TestUtils.getValueBits;
+import static com.android.server.testutils.TestUtils.assertExpectException;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.integrity.AppInstallMetadata;
+import android.content.integrity.AtomicFormula;
+import android.content.integrity.CompoundFormula;
+import android.content.integrity.Formula;
+import android.content.integrity.Rule;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Optional;
+
+@RunWith(JUnit4.class)
+public class RuleBinarySerializerTest {
+
+ private static final String COMPOUND_FORMULA_START_BITS =
+ getBits(COMPOUND_FORMULA_START, SEPARATOR_BITS);
+ private static final String COMPOUND_FORMULA_END_BITS =
+ getBits(COMPOUND_FORMULA_END, SEPARATOR_BITS);
+ private static final String ATOMIC_FORMULA_START_BITS =
+ getBits(ATOMIC_FORMULA_START, SEPARATOR_BITS);
+
+ private static final String NOT = getBits(CompoundFormula.NOT, CONNECTOR_BITS);
+ private static final String AND = getBits(CompoundFormula.AND, CONNECTOR_BITS);
+ private static final String OR = getBits(CompoundFormula.OR, CONNECTOR_BITS);
+
+ private static final String PACKAGE_NAME = getBits(AtomicFormula.PACKAGE_NAME, KEY_BITS);
+ private static final String APP_CERTIFICATE = getBits(AtomicFormula.APP_CERTIFICATE, KEY_BITS);
+ private static final String VERSION_CODE = getBits(AtomicFormula.VERSION_CODE, KEY_BITS);
+ private static final String PRE_INSTALLED = getBits(AtomicFormula.PRE_INSTALLED, KEY_BITS);
+
+ private static final String EQ = getBits(AtomicFormula.EQ, OPERATOR_BITS);
+
+ private static final String IS_NOT_HASHED = "0";
+
+ private static final String DENY = getBits(Rule.DENY, EFFECT_BITS);
+
+ private static final String START_BIT = "1";
+ private static final String END_BIT = "1";
+
+ private static final byte[] DEFAULT_FORMAT_VERSION_BYTES =
+ getBytes(getBits(DEFAULT_FORMAT_VERSION, FORMAT_VERSION_BITS));
+
+ @Test
+ public void testBinaryString_serializeEmptyRule() throws Exception {
+ Rule rule = null;
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+
+ assertExpectException(
+ RuleSerializeException.class,
+ /* expectedExceptionMessageRegex= */ "Null rule can not be serialized",
+ () ->
+ binarySerializer.serialize(
+ Collections.singletonList(rule),
+ /* formatVersion= */ Optional.empty()));
+ }
+
+ @Test
+ public void testBinaryStream_serializeValidCompoundFormula() throws Exception {
+ String packageName = "com.test.app";
+ Rule rule =
+ new Rule(
+ new CompoundFormula(
+ CompoundFormula.NOT,
+ Collections.singletonList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ String expectedBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + NOT
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
+ byteArrayOutputStream.write(getBytes(expectedBits));
+ byte[] expectedRules = byteArrayOutputStream.toByteArray();
+
+ binarySerializer.serialize(
+ Collections.singletonList(rule),
+ /* formatVersion= */ Optional.empty(),
+ outputStream);
+
+ byte[] actualRules = outputStream.toByteArray();
+ assertThat(actualRules).isEqualTo(expectedRules);
+ }
+
+ @Test
+ public void testBinaryString_serializeValidCompoundFormula_notConnector() throws Exception {
+ String packageName = "com.test.app";
+ Rule rule =
+ new Rule(
+ new CompoundFormula(
+ CompoundFormula.NOT,
+ Collections.singletonList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+ String expectedBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + NOT
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
+ byteArrayOutputStream.write(getBytes(expectedBits));
+ byte[] expectedRules = byteArrayOutputStream.toByteArray();
+
+ byte[] actualRules =
+ binarySerializer.serialize(
+ Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
+
+ assertThat(actualRules).isEqualTo(expectedRules);
+ }
+
+ @Test
+ public void testBinaryString_serializeValidCompoundFormula_andConnector() throws Exception {
+ String packageName = "com.test.app";
+ String appCertificate = "test_cert";
+ Rule rule =
+ new Rule(
+ new CompoundFormula(
+ CompoundFormula.AND,
+ Arrays.asList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false),
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.APP_CERTIFICATE,
+ appCertificate,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+ String expectedBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + AND
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + ATOMIC_FORMULA_START_BITS
+ + APP_CERTIFICATE
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(appCertificate.length(), VALUE_SIZE_BITS)
+ + getValueBits(appCertificate)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
+ byteArrayOutputStream.write(getBytes(expectedBits));
+ byte[] expectedRules = byteArrayOutputStream.toByteArray();
+
+ byte[] actualRules =
+ binarySerializer.serialize(
+ Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
+
+ assertThat(actualRules).isEqualTo(expectedRules);
+ }
+
+ @Test
+ public void testBinaryString_serializeValidCompoundFormula_orConnector() throws Exception {
+ String packageName = "com.test.app";
+ String appCertificate = "test_cert";
+ Rule rule =
+ new Rule(
+ new CompoundFormula(
+ CompoundFormula.OR,
+ Arrays.asList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false),
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.APP_CERTIFICATE,
+ appCertificate,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+ String expectedBits =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + OR
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + ATOMIC_FORMULA_START_BITS
+ + APP_CERTIFICATE
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(appCertificate.length(), VALUE_SIZE_BITS)
+ + getValueBits(appCertificate)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
+ byteArrayOutputStream.write(getBytes(expectedBits));
+ byte[] expectedRules = byteArrayOutputStream.toByteArray();
+
+ byte[] actualRules =
+ binarySerializer.serialize(
+ Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
+
+ assertThat(actualRules).isEqualTo(expectedRules);
+ }
+
+ @Test
+ public void testBinaryString_serializeValidAtomicFormula_stringValue() throws Exception {
+ String packageName = "com.test.app";
+ Rule rule =
+ new Rule(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false),
+ Rule.DENY);
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+ String expectedBits =
+ START_BIT
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + DENY
+ + END_BIT;
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
+ byteArrayOutputStream.write(getBytes(expectedBits));
+ byte[] expectedRules = byteArrayOutputStream.toByteArray();
+
+ byte[] actualRules =
+ binarySerializer.serialize(
+ Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
+
+ assertThat(actualRules).isEqualTo(expectedRules);
+ }
+
+ @Test
+ public void testBinaryString_serializeValidAtomicFormula_integerValue() throws Exception {
+ String versionCode = "1";
+ Rule rule =
+ new Rule(
+ new AtomicFormula.IntAtomicFormula(
+ AtomicFormula.VERSION_CODE,
+ AtomicFormula.EQ,
+ Integer.parseInt(versionCode)),
+ Rule.DENY);
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+ String expectedBits =
+ START_BIT
+ + ATOMIC_FORMULA_START_BITS
+ + VERSION_CODE
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(versionCode.length(), VALUE_SIZE_BITS)
+ + getValueBits(versionCode)
+ + DENY
+ + END_BIT;
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
+ byteArrayOutputStream.write(getBytes(expectedBits));
+ byte[] expectedRules = byteArrayOutputStream.toByteArray();
+
+ byte[] actualRules =
+ binarySerializer.serialize(
+ Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
+
+ assertThat(actualRules).isEqualTo(expectedRules);
+ }
+
+ @Test
+ public void testBinaryString_serializeValidAtomicFormula_booleanValue() throws Exception {
+ String preInstalled = "1";
+ Rule rule =
+ new Rule(
+ new AtomicFormula.BooleanAtomicFormula(AtomicFormula.PRE_INSTALLED, true),
+ Rule.DENY);
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+ String expectedBits =
+ START_BIT
+ + ATOMIC_FORMULA_START_BITS
+ + PRE_INSTALLED
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(preInstalled.length(), VALUE_SIZE_BITS)
+ + getValueBits(preInstalled)
+ + DENY
+ + END_BIT;
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
+ byteArrayOutputStream.write(getBytes(expectedBits));
+ byte[] expectedRules = byteArrayOutputStream.toByteArray();
+
+ byte[] actualRules =
+ binarySerializer.serialize(
+ Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
+
+ assertThat(actualRules).isEqualTo(expectedRules);
+ }
+
+ @Test
+ public void testBinaryString_serializeInvalidFormulaType() throws Exception {
+ Formula invalidFormula = getInvalidFormula();
+ Rule rule = new Rule(invalidFormula, Rule.DENY);
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+
+ assertExpectException(
+ RuleSerializeException.class,
+ /* expectedExceptionMessageRegex= */ "Invalid formula type",
+ () ->
+ binarySerializer.serialize(
+ Collections.singletonList(rule),
+ /* formatVersion= */ Optional.empty()));
+ }
+
+ @Test
+ public void testBinaryString_serializeFormatVersion() throws Exception {
+ int formatVersion = 1;
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+ String expectedBits = getBits(formatVersion, FORMAT_VERSION_BITS);
+ byte[] expectedRules = getBytes(expectedBits);
+
+ byte[] actualRules =
+ binarySerializer.serialize(
+ Collections.emptyList(), /* formatVersion= */ Optional.of(formatVersion));
+
+ assertThat(actualRules).isEqualTo(expectedRules);
+ }
+
+ private static Formula getInvalidFormula() {
+ return new Formula() {
+ @Override
+ public boolean isSatisfied(AppInstallMetadata appInstallMetadata) {
+ return false;
+ }
+
+ @Override
+ public int getTag() {
+ return 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return super.equals(obj);
+ }
+
+ @NonNull
+ @Override
+ protected Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+
+ @Override
+ public String toString() {
+ return super.toString();
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ }
+ };
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
index 5903b5a..ad74901 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
@@ -91,7 +91,7 @@
}
@Test
- public void testXmlStream_serializeValidOpenFormula() throws Exception {
+ public void testXmlStream_serializeValidCompoundFormula() throws Exception {
Rule rule =
new Rule(
new CompoundFormula(
@@ -134,7 +134,7 @@
}
@Test
- public void testXmlString_serializeValidOpenFormula_notConnector() throws Exception {
+ public void testXmlString_serializeValidCompoundFormula_notConnector() throws Exception {
Rule rule =
new Rule(
new CompoundFormula(
@@ -174,7 +174,7 @@
}
@Test
- public void testXmlString_serializeValidOpenFormula_andConnector() throws Exception {
+ public void testXmlString_serializeValidCompoundFormula_andConnector() throws Exception {
Rule rule =
new Rule(
new CompoundFormula(
@@ -224,7 +224,7 @@
}
@Test
- public void testXmlString_serializeValidOpenFormula_orConnector() throws Exception {
+ public void testXmlString_serializeValidCompoundFormula_orConnector() throws Exception {
Rule rule =
new Rule(
new CompoundFormula(
diff --git a/services/tests/servicestests/src/com/android/server/integrity/utils/TestUtils.java b/services/tests/servicestests/src/com/android/server/integrity/utils/TestUtils.java
new file mode 100644
index 0000000..e54410b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/utils/TestUtils.java
@@ -0,0 +1,48 @@
+/*
+ * 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.server.integrity.utils;
+
+public class TestUtils {
+
+ public static String getBits(int component, int numOfBits) {
+ return String.format("%" + numOfBits + "s", Integer.toBinaryString(component))
+ .replace(' ', '0');
+ }
+
+ public static String getValueBits(String value) {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (byte valueByte : value.getBytes()) {
+ stringBuilder.append(getBits(valueByte, /* numOfBits= */ 8));
+ }
+ return stringBuilder.toString();
+ }
+
+ public static byte[] getBytes(String bits) {
+ int bitStringSize = bits.length();
+ int numOfBytes = bitStringSize / 8;
+ if (bitStringSize % 8 != 0) {
+ numOfBytes++;
+ }
+ byte[] bytes = new byte[numOfBytes];
+ for (int i = 0; i < bits.length(); i++) {
+ if (bits.charAt(i) == '1') {
+ bytes[i / 8] |= 1 << (7 - (i % 8));
+ }
+ }
+ return bytes;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 51bae16..545836e 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -138,7 +138,6 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent;
import com.android.server.DeviceIdleInternal;
@@ -1484,7 +1483,7 @@
// smoke test to make sure no errors are raised
mServiceContext.sendBroadcast(
new Intent(ACTION_CARRIER_CONFIG_CHANGED)
- .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
);
assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
true);
@@ -1499,7 +1498,7 @@
bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, -100);
mServiceContext.sendBroadcast(
new Intent(ACTION_CARRIER_CONFIG_CHANGED)
- .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
);
assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
@@ -1518,7 +1517,7 @@
DATA_CYCLE_USE_PLATFORM_DEFAULT);
mServiceContext.sendBroadcast(
new Intent(ACTION_CARRIER_CONFIG_CHANGED)
- .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
);
assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
@@ -1540,7 +1539,7 @@
DATA_CYCLE_THRESHOLD_DISABLED);
mServiceContext.sendBroadcast(
new Intent(ACTION_CARRIER_CONFIG_CHANGED)
- .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
);
// The policy still shouldn't change, because we don't want to overwrite user settings.
@@ -1557,7 +1556,7 @@
bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, 9999);
mServiceContext.sendBroadcast(
new Intent(ACTION_CARRIER_CONFIG_CHANGED)
- .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
);
assertNetworkPolicyEquals(31, 9999, 9999, true);
@@ -1574,7 +1573,7 @@
DATA_CYCLE_THRESHOLD_DISABLED);
mServiceContext.sendBroadcast(
new Intent(ACTION_CARRIER_CONFIG_CHANGED)
- .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
);
assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
@@ -1591,7 +1590,7 @@
DATA_CYCLE_THRESHOLD_DISABLED);
mServiceContext.sendBroadcast(
new Intent(ACTION_CARRIER_CONFIG_CHANGED)
- .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
);
assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
@@ -1606,7 +1605,7 @@
DATA_CYCLE_USE_PLATFORM_DEFAULT);
mServiceContext.sendBroadcast(
new Intent(ACTION_CARRIER_CONFIG_CHANGED)
- .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
+ .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
);
assertNetworkPolicyEquals(31, mDefaultWarningBytes, mDefaultLimitBytes,
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 0ca62e2..81fb0ec 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -61,7 +61,6 @@
import android.os.PowerManager;
import android.os.PowerSaveState;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.test.mock.MockContentResolver;
@@ -97,10 +96,12 @@
* Tests for {@link com.android.server.power.PowerManagerService}
*/
public class PowerManagerServiceTest {
+ private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent";
+ private static final String SYSTEM_PROPERTY_REBOOT_REASON = "sys.boot.reason";
+
private static final float PRECISION = 0.001f;
private static final float BRIGHTNESS_FACTOR = 0.7f;
private static final boolean BATTERY_SAVER_ENABLED = true;
- private static final String TEST_LAST_REBOOT_PROPERTY = "test.sys.boot.reason";
@Mock private BatterySaverPolicy mBatterySaverPolicyMock;
@Mock private LightsManager mLightsManagerMock;
@@ -112,6 +113,7 @@
@Mock private Notifier mNotifierMock;
@Mock private WirelessChargerDetector mWirelessChargerDetectorMock;
@Mock private AmbientDisplayConfiguration mAmbientDisplayConfigurationMock;
+ @Mock private SystemPropertiesWrapper mSystemPropertiesMock;
@Mock
private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock;
@@ -159,6 +161,7 @@
when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(false);
when(mInattentiveSleepWarningControllerMock.isShown()).thenReturn(false);
when(mDisplayManagerInternalMock.requestPowerState(any(), anyBoolean())).thenReturn(true);
+ when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), anyString())).thenReturn("");
mDisplayPowerRequest = new DisplayPowerRequest();
addLocalServiceMock(LightsManager.class, mLightsManagerMock);
@@ -218,6 +221,11 @@
InattentiveSleepWarningController createInattentiveSleepWarningController() {
return mInattentiveSleepWarningControllerMock;
}
+
+ @Override
+ public SystemPropertiesWrapper createSystemPropertiesWrapper() {
+ return mSystemPropertiesMock;
+ }
});
return mService;
}
@@ -228,12 +236,6 @@
LocalServices.removeServiceForTest(DisplayManagerInternal.class);
LocalServices.removeServiceForTest(BatteryManagerInternal.class);
LocalServices.removeServiceForTest(ActivityManagerInternal.class);
-
- Settings.Global.putInt(
- mContextSpy.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0);
- setAttentiveTimeout(-1);
- Settings.Global.putInt(mContextSpy.getContentResolver(),
- Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
}
/**
@@ -322,10 +324,10 @@
@Test
public void testGetLastShutdownReasonInternal() {
+ when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_REBOOT_REASON), any())).thenReturn(
+ "shutdown,thermal");
createService();
- SystemProperties.set(TEST_LAST_REBOOT_PROPERTY, "shutdown,thermal");
- int reason = mService.getLastShutdownReasonInternal(TEST_LAST_REBOOT_PROPERTY);
- SystemProperties.set(TEST_LAST_REBOOT_PROPERTY, "");
+ int reason = mService.getLastShutdownReasonInternal();
assertThat(reason).isEqualTo(PowerManager.SHUTDOWN_REASON_THERMAL_SHUTDOWN);
}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeDetectorStrategyTest.java b/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeDetectorStrategyTest.java
index 8a7edf7..7a0a28d 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeDetectorStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeDetectorStrategyTest.java
@@ -640,9 +640,9 @@
private static PhoneTimeSuggestion createPhoneTimeSuggestion(int phoneId,
TimestampedValue<Long> utcTime) {
- PhoneTimeSuggestion timeSuggestion = new PhoneTimeSuggestion(phoneId);
- timeSuggestion.setUtcTime(utcTime);
- return timeSuggestion;
+ return new PhoneTimeSuggestion.Builder(phoneId)
+ .setUtcTime(utcTime)
+ .build();
}
private ManualTimeSuggestion createManualTimeSuggestion(long timeMillis) {
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index 9951e85..84b495f 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -140,10 +140,10 @@
private static PhoneTimeSuggestion createPhoneTimeSuggestion() {
int phoneId = 1234;
- PhoneTimeSuggestion suggestion = new PhoneTimeSuggestion(phoneId);
TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
- suggestion.setUtcTime(timeValue);
- return suggestion;
+ return new PhoneTimeSuggestion.Builder(phoneId)
+ .setUtcTime(timeValue)
+ .build();
}
private static ManualTimeSuggestion createManualTimeSuggestion() {
diff --git a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
index e32103f..e6bb244 100644
--- a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
+++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
@@ -45,6 +45,7 @@
import java.io.IOException;
import java.util.List;
import java.util.Locale;
+import java.util.Set;
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -93,6 +94,8 @@
for (File f : usageFiles) {
f.delete();
}
+ } else {
+ intervalDir.delete();
}
}
}
@@ -587,6 +590,7 @@
db.readMappingsLocked();
db.init(1);
db.putUsageStats(interval, mIntervalStats);
+ db.writeMappingsLocked();
final String removedPackage = "fake.package.name0";
// invoke handler call directly from test to remove package
@@ -594,19 +598,19 @@
List<IntervalStats> stats = db.queryUsageStats(interval, 0, mEndTime,
mIntervalStatsVerifier);
- for (int i = 0; i < stats.size(); i++) {
- final IntervalStats stat = stats.get(i);
- if (stat.packageStats.containsKey(removedPackage)) {
- fail("Found removed package " + removedPackage + " in package stats.");
+ assertEquals(1, stats.size(),
+ "Only one interval stats object should exist for the given time range.");
+ final IntervalStats stat = stats.get(0);
+ if (stat.packageStats.containsKey(removedPackage)) {
+ fail("Found removed package " + removedPackage + " in package stats.");
+ return;
+ }
+ for (int i = 0; i < stat.events.size(); i++) {
+ final Event event = stat.events.get(i);
+ if (removedPackage.equals(event.mPackage)) {
+ fail("Found an event from removed package " + removedPackage);
return;
}
- for (int j = 0; j < stat.events.size(); j++) {
- final Event event = stat.events.get(j);
- if (removedPackage.equals(event.mPackage)) {
- fail("Found an event from removed package " + removedPackage);
- return;
- }
- }
}
}
@@ -617,4 +621,90 @@
verifyPackageNotRetained(UsageStatsManager.INTERVAL_MONTHLY);
verifyPackageNotRetained(UsageStatsManager.INTERVAL_YEARLY);
}
+
+ private void verifyPackageDataIsRemoved(UsageStatsDatabase db, int interval,
+ String removedPackage) {
+ List<IntervalStats> stats = db.queryUsageStats(interval, 0, mEndTime,
+ mIntervalStatsVerifier);
+ assertEquals(1, stats.size(),
+ "Only one interval stats object should exist for the given time range.");
+ final IntervalStats stat = stats.get(0);
+ if (stat.packageStats.containsKey(removedPackage)) {
+ fail("Found removed package " + removedPackage + " in package stats.");
+ return;
+ }
+ for (int i = 0; i < stat.events.size(); i++) {
+ final Event event = stat.events.get(i);
+ if (removedPackage.equals(event.mPackage)) {
+ fail("Found an event from removed package " + removedPackage);
+ return;
+ }
+ }
+ }
+
+ private void verifyPackageDataIsNotRemoved(UsageStatsDatabase db, int interval,
+ Set<String> installedPackages) {
+ List<IntervalStats> stats = db.queryUsageStats(interval, 0, mEndTime,
+ mIntervalStatsVerifier);
+ assertEquals(1, stats.size(),
+ "Only one interval stats object should exist for the given time range.");
+ final IntervalStats stat = stats.get(0);
+ if (!stat.packageStats.containsAll(installedPackages)) {
+ fail("Could not find some installed packages in package stats.");
+ return;
+ }
+ // attempt to find an event from each installed package
+ for (String installedPackage : installedPackages) {
+ for (int i = 0; i < stat.events.size(); i++) {
+ if (installedPackage.equals(stat.events.get(i).mPackage)) {
+ break;
+ }
+ if (i == stat.events.size() - 1) {
+ fail("Could not find any event for: " + installedPackage);
+ return;
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testPackageDataIsRemoved() throws IOException {
+ UsageStatsDatabase db = new UsageStatsDatabase(mTestDir);
+ db.readMappingsLocked();
+ db.init(1);
+
+ // write stats to disk for each interval
+ db.putUsageStats(UsageStatsManager.INTERVAL_DAILY, mIntervalStats);
+ db.putUsageStats(UsageStatsManager.INTERVAL_WEEKLY, mIntervalStats);
+ db.putUsageStats(UsageStatsManager.INTERVAL_MONTHLY, mIntervalStats);
+ db.putUsageStats(UsageStatsManager.INTERVAL_YEARLY, mIntervalStats);
+ db.writeMappingsLocked();
+
+ final Set<String> installedPackages = mIntervalStats.packageStats.keySet();
+ final String removedPackage = installedPackages.iterator().next();
+ installedPackages.remove(removedPackage);
+
+ // mimic a package uninstall
+ db.onPackageRemoved(removedPackage, System.currentTimeMillis());
+
+ // mimic the idle prune job being triggered
+ db.pruneUninstalledPackagesData();
+
+ // read data from disk into a new db instance
+ UsageStatsDatabase newDB = new UsageStatsDatabase(mTestDir);
+ newDB.readMappingsLocked();
+ newDB.init(mEndTime);
+
+ // query data for each interval and ensure data for package doesn't exist
+ verifyPackageDataIsRemoved(newDB, UsageStatsManager.INTERVAL_DAILY, removedPackage);
+ verifyPackageDataIsRemoved(newDB, UsageStatsManager.INTERVAL_WEEKLY, removedPackage);
+ verifyPackageDataIsRemoved(newDB, UsageStatsManager.INTERVAL_MONTHLY, removedPackage);
+ verifyPackageDataIsRemoved(newDB, UsageStatsManager.INTERVAL_YEARLY, removedPackage);
+
+ // query data for each interval and ensure some data for installed packages exists
+ verifyPackageDataIsNotRemoved(newDB, UsageStatsManager.INTERVAL_DAILY, installedPackages);
+ verifyPackageDataIsNotRemoved(newDB, UsageStatsManager.INTERVAL_WEEKLY, installedPackages);
+ verifyPackageDataIsNotRemoved(newDB, UsageStatsManager.INTERVAL_MONTHLY, installedPackages);
+ verifyPackageDataIsNotRemoved(newDB, UsageStatsManager.INTERVAL_YEARLY, installedPackages);
+ }
}
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 5336811..de2bba2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -123,7 +123,7 @@
assertTrue(stack1.isFocusedStackOnDisplay());
// Stack2 should be focused after removing stack1.
- display.removeChild(stack1);
+ display.removeStack(stack1);
assertTrue(stack2.isFocusedStackOnDisplay());
}
@@ -224,7 +224,7 @@
final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
.setStack(alwaysOnTopStack).build();
alwaysOnTopStack.setAlwaysOnTop(true);
- display.positionChildAtTop(alwaysOnTopStack, false /* includingParents */);
+ display.positionStackAtTop(alwaysOnTopStack, false /* includingParents */);
assertTrue(alwaysOnTopStack.isAlwaysOnTop());
// Ensure always on top state is synced to the children of the stack.
assertTrue(alwaysOnTopStack.getTopNonFinishingActivity().isAlwaysOnTop());
@@ -238,36 +238,36 @@
final ActivityStack anotherAlwaysOnTopStack = display.createStack(
WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
anotherAlwaysOnTopStack.setAlwaysOnTop(true);
- display.positionChildAtTop(anotherAlwaysOnTopStack, false /* includingParents */);
+ display.positionStackAtTop(anotherAlwaysOnTopStack, false /* includingParents */);
assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop());
- int topPosition = display.getChildCount() - 1;
+ int topPosition = display.getStackCount() - 1;
// Ensure the new alwaysOnTop stack is put below the pinned stack, but on top of the
// existing alwaysOnTop stack.
- assertEquals(anotherAlwaysOnTopStack, display.getChildAt(topPosition - 1));
+ assertEquals(anotherAlwaysOnTopStack, display.getStackAt(topPosition - 1));
final ActivityStack nonAlwaysOnTopStack = display.createStack(
WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
assertEquals(display, nonAlwaysOnTopStack.getDisplay());
- topPosition = display.getChildCount() - 1;
+ topPosition = display.getStackCount() - 1;
// Ensure the non-alwaysOnTop stack is put below the three alwaysOnTop stacks, but above the
// existing other non-alwaysOnTop stacks.
- assertEquals(nonAlwaysOnTopStack, display.getChildAt(topPosition - 3));
+ assertEquals(nonAlwaysOnTopStack, display.getStackAt(topPosition - 3));
anotherAlwaysOnTopStack.setAlwaysOnTop(false);
- display.positionChildAtTop(anotherAlwaysOnTopStack, false /* includingParents */);
+ display.positionStackAtTop(anotherAlwaysOnTopStack, false /* includingParents */);
assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop());
// Ensure, when always on top is turned off for a stack, the stack is put just below all
// other always on top stacks.
- assertEquals(anotherAlwaysOnTopStack, display.getChildAt(topPosition - 2));
+ assertEquals(anotherAlwaysOnTopStack, display.getStackAt(topPosition - 2));
anotherAlwaysOnTopStack.setAlwaysOnTop(true);
// Ensure always on top state changes properly when windowing mode changes.
anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop());
- assertEquals(anotherAlwaysOnTopStack, display.getChildAt(topPosition - 2));
+ assertEquals(anotherAlwaysOnTopStack, display.getStackAt(topPosition - 2));
anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FREEFORM);
assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop());
- assertEquals(anotherAlwaysOnTopStack, display.getChildAt(topPosition - 1));
+ assertEquals(anotherAlwaysOnTopStack, display.getStackAt(topPosition - 1));
}
@Test
@@ -299,14 +299,14 @@
// Reordering stacks while removing stacks.
doAnswer(invocation -> {
- display.positionChildAtTop(stack3, false);
+ display.positionStackAtTop(stack3, false);
return true;
}).when(mSupervisor).removeTaskByIdLocked(eq(task4.mTaskId), anyBoolean(), anyBoolean(),
any());
// Removing stacks from the display while removing stacks.
doAnswer(invocation -> {
- display.removeChild(stack2);
+ display.removeStack(stack2);
return true;
}).when(mSupervisor).removeTaskByIdLocked(eq(task2.mTaskId), anyBoolean(), anyBoolean(),
any());
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index c2b8827..7166829 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -455,7 +455,7 @@
verify(mService.getLifecycleManager()).scheduleTransaction(
eq(mActivity.app.getThread()), eq(mActivity.appToken), eq(expected));
} finally {
- stack.getDisplay().removeChild(stack);
+ stack.getDisplay().removeStack(stack);
}
}
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 c8795ce..7806d40 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -290,7 +290,7 @@
verify(stack2).positionChildAtBottom(any(), eq(false) /* includingParents */);
// Also move display to back because there is only one stack left.
- display.removeChild(stack1);
+ display.removeStack(stack1);
stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.topTask());
verify(stack2).positionChildAtBottom(any(), eq(true) /* includingParents */);
}
@@ -576,7 +576,7 @@
@Test
public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
- mDefaultDisplay.removeChild(mStack);
+ mDefaultDisplay.removeStack(mStack);
final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
@@ -595,7 +595,7 @@
@Test
public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
- mDefaultDisplay.removeChild(mStack);
+ mDefaultDisplay.removeStack(mStack);
final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
@@ -614,7 +614,7 @@
@Test
public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
- mDefaultDisplay.removeChild(mStack);
+ mDefaultDisplay.removeStack(mStack);
final ActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
@@ -633,7 +633,7 @@
@Test
public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
- mDefaultDisplay.removeChild(mStack);
+ mDefaultDisplay.removeStack(mStack);
final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
@@ -660,7 +660,7 @@
@Test
public void
testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
- mDefaultDisplay.removeChild(mStack);
+ mDefaultDisplay.removeStack(mStack);
final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
@@ -684,7 +684,7 @@
@Test
public void testMoveHomeStackBehindStack_BehindHomeStack() {
- mDefaultDisplay.removeChild(mStack);
+ mDefaultDisplay.removeStack(mStack);
final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
@@ -707,7 +707,7 @@
@Test
public void testMoveHomeStackBehindStack() {
- mDefaultDisplay.removeChild(mStack);
+ mDefaultDisplay.removeStack(mStack);
final ActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
@@ -814,16 +814,16 @@
}
@SuppressWarnings("TypeParameterUnusedInFormals")
- private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
+ private ActivityStack createStackForShouldBeVisibleTest(
ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
final ActivityStack stack;
if (activityType == ACTIVITY_TYPE_HOME) {
// Home stack and activity are created in ActivityTestsBase#setupActivityManagerService
stack = mDefaultDisplay.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
if (onTop) {
- mDefaultDisplay.positionChildAtTop(stack, false /* includingParents */);
+ mDefaultDisplay.positionStackAtTop(stack, false /* includingParents */);
} else {
- mDefaultDisplay.positionChildAtBottom(stack);
+ mDefaultDisplay.positionStackAtBottom(stack);
}
} else {
stack = new StackBuilder(mRootActivityContainer)
@@ -834,7 +834,7 @@
.setCreateActivity(true)
.build();
}
- return (T) stack;
+ return stack;
}
@Test
@@ -1051,7 +1051,7 @@
StackOrderChangedListener listener = new StackOrderChangedListener();
mDefaultDisplay.registerStackOrderChangedListener(listener);
try {
- mDefaultDisplay.removeChild(mStack);
+ mDefaultDisplay.removeStack(mStack);
} finally {
mDefaultDisplay.unregisterStackOrderChangedListener(listener);
}
@@ -1060,12 +1060,12 @@
@Test
public void testStackOrderChangedOnAddPositionStack() {
- mDefaultDisplay.removeChild(mStack);
+ mDefaultDisplay.removeStack(mStack);
StackOrderChangedListener listener = new StackOrderChangedListener();
mDefaultDisplay.registerStackOrderChangedListener(listener);
try {
- mDefaultDisplay.addChild(mStack, 0);
+ mDefaultDisplay.addStack(mStack, 0);
} finally {
mDefaultDisplay.unregisterStackOrderChangedListener(listener);
}
@@ -1080,7 +1080,7 @@
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
mDefaultDisplay.registerStackOrderChangedListener(listener);
- mDefaultDisplay.positionChildAtBottom(fullscreenStack1);
+ mDefaultDisplay.positionStackAtBottom(fullscreenStack1);
} finally {
mDefaultDisplay.unregisterStackOrderChangedListener(listener);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index c712d6d..d5fdf98 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -517,8 +517,8 @@
}
private void assertNoTasks(ActivityDisplay display) {
- for (int i = display.getChildCount() - 1; i >= 0; --i) {
- final ActivityStack stack = display.getChildAt(i);
+ for (int i = display.getStackCount() - 1; i >= 0; --i) {
+ final ActivityStack stack = display.getStackAt(i);
assertThat(stack.getAllTasks()).isEmpty();
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 7322ac3..0021cc5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -203,6 +203,15 @@
}
ActivityRecord build() {
+ try {
+ mService.deferWindowLayout();
+ return buildInner();
+ } finally {
+ mService.continueWindowLayout();
+ }
+ }
+
+ ActivityRecord buildInner() {
if (mComponent == null) {
final int id = sCurrentActivityId++;
mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
@@ -236,7 +245,7 @@
ActivityOptions options = null;
if (mLaunchTaskBehind) {
- options = ActivityOptions.makeTaskLaunchBehind();
+ options = ActivityOptions.makeTaskLaunchBehind();
}
final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
@@ -399,11 +408,18 @@
return this;
}
+ // TODO(display-merge): Remove
StackBuilder setDisplay(ActivityDisplay display) {
mDisplay = display;
return this;
}
+ StackBuilder setDisplay(DisplayContent display) {
+ // TODO(display-merge): Remove cast
+ mDisplay = (ActivityDisplay) display;
+ return this;
+ }
+
StackBuilder setOnTop(boolean onTop) {
mOnTop = onTop;
return this;
diff --git a/services/tests/wmtests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BoundsAnimationControllerTests.java
index beec1a8..0ad0f95 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BoundsAnimationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -47,6 +47,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Test class for {@link BoundsAnimationController} to ensure that it sends the right callbacks
@@ -63,6 +64,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class BoundsAnimationControllerTests extends WindowTestsBase {
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
index 73420a0..0aa6961 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
@@ -36,12 +36,14 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Build/Install/Run:
* atest FrameworksServicesTests:DimmerTests
*/
@Presubmit
+@RunWith(WindowTestRunner.class)
public class DimmerTests extends WindowTestsBase {
private static class TestWindowContainer extends WindowContainer<TestWindowContainer> {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 3eda980..716e777 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -709,13 +709,13 @@
final ActivityStack stack =
new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
- .setDisplay(dc.mActivityDisplay)
+ .setDisplay(dc)
.build();
doReturn(true).when(stack).isVisible();
final ActivityStack freeformStack =
new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
- .setDisplay(dc.mActivityDisplay)
+ .setDisplay(dc)
.setWindowingMode(WINDOWING_MODE_FREEFORM)
.build();
doReturn(true).when(freeformStack).isVisible();
@@ -743,7 +743,7 @@
final ActivityStack stack =
new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
- .setDisplay(dc.mActivityDisplay).build();
+ .setDisplay(dc).build();
final ActivityRecord activity = stack.topTask().getTopNonFinishingActivity();
activity.setRequestedOrientation(newOrientation);
@@ -765,12 +765,13 @@
final ActivityStack stack =
new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
- .setDisplay(dc.mActivityDisplay).build();
+ .setDisplay(dc).build();
final ActivityRecord activity = stack.topTask().getTopNonFinishingActivity();
activity.setRequestedOrientation(newOrientation);
- verify(dc.mActivityDisplay, never()).updateDisplayOverrideConfigurationLocked(any(),
+ // TODO(display-merge): Remove cast
+ verify((ActivityDisplay) dc, never()).updateDisplayOverrideConfigurationLocked(any(),
eq(activity), anyBoolean(), same(null));
assertEquals(dc.getDisplayRotation().getUserRotation(), dc.getRotation());
}
@@ -940,6 +941,7 @@
final DisplayContent displayContent = createNewDisplay();
Mockito.doReturn(mockLogger).when(displayContent).getMetricsLogger();
Mockito.doReturn(oldConfig).doReturn(newConfig).when(displayContent).getConfiguration();
+ doNothing().when(displayContent).preOnConfigurationChanged();
displayContent.onConfigurationChanged(newConfig);
@@ -959,12 +961,12 @@
Mockito.doCallRealMethod().when(dr).updateRotationUnchecked(anyBoolean());
Mockito.doReturn(ROTATION_90).when(dr).rotationForOrientation(anyInt(), anyInt());
final boolean[] continued = new boolean[1];
- spyOn(dc.mActivityDisplay);
+ // TODO(display-merge): Remove cast
Mockito.doAnswer(
invocation -> {
continued[0] = true;
return true;
- }).when(dc.mActivityDisplay).updateDisplayOverrideConfigurationLocked();
+ }).when((ActivityDisplay) dc).updateDisplayOverrideConfigurationLocked();
final boolean[] called = new boolean[1];
mWm.mDisplayRotationController =
new IDisplayWindowRotationController.Stub() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java
index 6767465..f754c59 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java
@@ -32,9 +32,11 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
+import org.junit.runner.RunWith;
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase {
@Rule
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
index 79ad0c4..9e5d9da 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -46,6 +46,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.io.File;
@@ -63,6 +64,7 @@
*/
@MediumTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class LaunchParamsPersisterTests extends ActivityTestsBase {
private static final int TEST_USER_ID = 3;
private static final int ALTERNATIVE_USER_ID = 0;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 4f2d5d2..9f97c48 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -977,9 +977,9 @@
private void assertNotRestoreTask(Runnable action) {
// Verify stack count doesn't change because task with fullscreen mode and standard type
// would have its own stack.
- final int orignalStackCount = mDisplay.getChildCount();
+ final int originalStackCount = mDisplay.getStackCount();
action.run();
- assertEquals(orignalStackCount, mDisplay.getChildCount());
+ assertEquals(originalStackCount, mDisplay.getStackCount());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 1abd366..2374847 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -138,7 +138,8 @@
@Test
public void testIncludedApps_expectTargetAndVisible() {
mWm.setRecentsAnimationController(mController);
- final ActivityStack homeStack = mDisplayContent.mActivityDisplay.getOrCreateStack(
+ // TODO(display-merge): Remove cast
+ final ActivityStack homeStack = ((ActivityDisplay) mDisplayContent).getOrCreateStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
final ActivityRecord homeActivity =
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
@@ -163,7 +164,8 @@
@Test
public void testWallpaperIncluded_expectTarget() throws Exception {
mWm.setRecentsAnimationController(mController);
- final ActivityStack homeStack = mDisplayContent.mActivityDisplay.getOrCreateStack(
+ // TODO(display-merge): Remove cast
+ final ActivityStack homeStack = ((ActivityDisplay) mDisplayContent).getOrCreateStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
final ActivityRecord homeAppWindow =
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
@@ -192,7 +194,8 @@
@Test
public void testWallpaperAnimatorCanceled_expectAnimationKeepsRunning() throws Exception {
mWm.setRecentsAnimationController(mController);
- final ActivityStack homeStack = mDisplayContent.mActivityDisplay.getOrCreateStack(
+ // TODO(display-merge): Remove cast
+ final ActivityStack homeStack = ((ActivityDisplay) mDisplayContent).getOrCreateStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
final ActivityRecord homeActivity =
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
@@ -223,7 +226,8 @@
@Test
public void testFinish_expectTargetAndWallpaperAdaptersRemoved() {
mWm.setRecentsAnimationController(mController);
- final ActivityStack homeStack = mDisplayContent.mActivityDisplay.getOrCreateStack(
+ // TODO(display-merge): Remove cast
+ final ActivityStack homeStack = ((ActivityDisplay) mDisplayContent).getOrCreateStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
final ActivityRecord homeActivity =
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index e67380c..4abab63 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -119,7 +119,7 @@
final ActivityDisplay defaultDisplay = mRootActivityContainer.getDefaultDisplay();
final ActivityStack homeStack =
defaultDisplay.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
- defaultDisplay.positionChildAtTop(homeStack, false /* includingParents */);
+ defaultDisplay.positionStackAtTop(homeStack, false /* includingParents */);
ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
if (topRunningHomeActivity == null) {
topRunningHomeActivity = new ActivityBuilder(mService)
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index e353903..112479b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -54,6 +54,7 @@
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;
@@ -64,6 +65,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class RemoteAnimationControllerTest extends WindowTestsBase {
@Mock SurfaceControl mMockLeash;
@@ -84,7 +86,7 @@
when(mMockRunner.asBinder()).thenReturn(new Binder());
mAdapter = new RemoteAnimationAdapter(mMockRunner, 100, 50, true /* changeNeedsSnapshot */);
mAdapter.setCallingPidUid(123, 456);
- mWm.mH.runWithScissors(() -> mHandler = new TestHandler(null, mClock), 0);
+ runWithScissors(mWm.mH, () -> mHandler = new TestHandler(null, mClock), 0);
mController = new RemoteAnimationController(mWm, mAdapter, mHandler);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 4257249..59c7c02 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -226,20 +226,20 @@
@Test
public void testRemovingStackOnAppCrash() {
final ActivityDisplay defaultDisplay = mRootActivityContainer.getDefaultDisplay();
- final int originalStackCount = defaultDisplay.getChildCount();
+ final int originalStackCount = defaultDisplay.getStackCount();
final ActivityStack stack = mRootActivityContainer.getDefaultDisplay().createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
.setStack(stack).build();
- assertEquals(originalStackCount + 1, defaultDisplay.getChildCount());
+ assertEquals(originalStackCount + 1, defaultDisplay.getStackCount());
// Let's pretend that the app has crashed.
firstActivity.app.setThread(null);
mRootActivityContainer.finishTopCrashedActivities(firstActivity.app, "test");
// Verify that the stack was removed.
- assertEquals(originalStackCount, defaultDisplay.getChildCount());
+ assertEquals(originalStackCount, defaultDisplay.getStackCount());
}
@Test
@@ -392,7 +392,7 @@
ACTIVITY_TYPE_STANDARD, false /* onTop */));
final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
final ActivityRecord activity = new ActivityBuilder(mService).setTask(task).build();
- display.positionChildAtBottom(targetStack);
+ display.positionStackAtBottom(targetStack);
// Assume the stack is not at the topmost position (e.g. behind always-on-top stacks) but it
// is the current top focused stack.
@@ -493,7 +493,7 @@
final Task task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
final ActivityRecord activity = new ActivityBuilder(mService).setTask(task).build();
activity.setState(ActivityState.RESUMED, "test");
- display.positionChildAtBottom(targetStack);
+ display.positionStackAtBottom(targetStack);
// Assume the stack is at the topmost position
assertFalse(targetStack.isTopStackOnDisplay());
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index eba2bc8..5c9ccae 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -74,7 +74,7 @@
final int numTasks = 10;
int activeTime = 0;
for (int i = 0; i < numTasks; i++) {
- createTask(display.getChildAt(i % numStacks), ".Task" + i, i, activeTime++);
+ createTask(display.getStackAt(i % numStacks), ".Task" + i, i, activeTime++);
}
// Ensure that the latest tasks were returned in order of decreasing last active time,
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
index c483489..3008a75 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
@@ -50,6 +50,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -63,6 +64,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class SurfaceAnimationRunnerTest extends WindowTestsBase {
@Mock SurfaceControl mMockSurface;
@@ -98,6 +100,7 @@
verify(mMockTransaction, atLeastOnce()).setMatrix(eq(mMockSurface), eq(m), any());
verify(mMockTransaction, atLeastOnce()).setAlpha(eq(mMockSurface), eq(1.0f));
+ waitHandlerIdle(SurfaceAnimationThread.getHandler());
mFinishCallbackLatch.await(1, SECONDS);
assertFinishCallbackCalled();
@@ -176,6 +179,7 @@
assertTrue(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
mSurfaceAnimationRunner.continueStartingAnimations();
waitUntilNextFrame();
+ waitHandlerIdle(SurfaceAnimationThread.getHandler());
assertFalse(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
mFinishCallbackLatch.await(1, SECONDS);
assertFinishCallbackCalled();
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 979aab6..2894241 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -44,6 +44,7 @@
import org.junit.After;
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;
@@ -56,6 +57,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class SurfaceAnimatorTest extends WindowTestsBase {
@Mock AnimationAdapter mSpec;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 27ebd5a..9a91efe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -53,6 +53,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.List;
@@ -66,6 +67,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
private static final Rect DISPLAY_BOUNDS = new Rect(/* left */ 0, /* top */ 0,
/* right */ 1920, /* bottom */ 1080);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
index 9275512..8970571 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
@@ -19,7 +19,6 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.TaskPositioner.MIN_ASPECT;
import static com.android.server.wm.WindowManagerService.dipToPixel;
@@ -33,7 +32,6 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import android.app.IActivityTaskManager;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.util.DisplayMetrics;
@@ -46,6 +44,7 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for the {@link TaskPositioner} class.
@@ -55,6 +54,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class TaskPositionerTests extends WindowTestsBase {
private static final boolean DEBUGGING = false;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
index f595e05..0274b7d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
@@ -18,21 +18,21 @@
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.app.ActivityManager.TaskSnapshot;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import android.app.ActivityManager.TaskSnapshot;
-
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
/**
* Test class for {@link TaskSnapshotCache}.
@@ -42,6 +42,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class TaskSnapshotCacheTest extends TaskSnapshotPersisterTestBase {
private TaskSnapshotCache mCache;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index 3b11003..6ebaf29 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -33,6 +33,7 @@
import com.google.android.collect.Sets;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Test class for {@link TaskSnapshotController}.
@@ -42,6 +43,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class TaskSnapshotControllerTest extends WindowTestsBase {
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index b29453a..b5a5790 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -38,6 +38,7 @@
import com.android.server.wm.TaskSnapshotPersister.RemoveObsoleteFilesQueueItem;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.io.File;
import java.util.function.Predicate;
@@ -50,6 +51,7 @@
*/
@MediumTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBase {
private static final Rect TEST_INSETS = new Rect(10, 20, 30, 40);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index 74db820..817344f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -47,6 +47,7 @@
import com.android.server.wm.TaskSnapshotSurface.Window;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Test class for {@link TaskSnapshotSurface}.
@@ -56,6 +57,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class TaskSnapshotSurfaceTest extends WindowTestsBase {
private TaskSnapshotSurface mSurface;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
index dbf61db..6ad9f74 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
@@ -19,6 +19,9 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
@@ -112,6 +115,10 @@
@Test
public void testDisplayPositionWithPinnedStack() {
+ // Make sure the display is system owned display which capable to move the stack to top.
+ spyOn(mDisplayContent);
+ doReturn(false).when(mDisplayContent).isUntrustedVirtualDisplay();
+
// The display contains pinned stack that was added in {@link #setUp}.
final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
final Task task = createTaskInStack(stack, 0 /* userId */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index aa6c14e..634d2f0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -368,7 +368,7 @@
}
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
}
@Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
index 64ac547..c359fb1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
@@ -48,6 +48,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Test class to for {@link android.app.WindowConfiguration}.
@@ -57,6 +58,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class WindowConfigurationTests extends WindowTestsBase {
private Rect mParentBounds;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 8140045..13cf22d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -56,6 +56,7 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mockito;
import java.util.Comparator;
@@ -68,6 +69,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class WindowContainerTests extends WindowTestsBase {
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
index 4b666f5..8936aad 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
@@ -31,6 +31,7 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.function.Consumer;
@@ -42,6 +43,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class WindowContainerTraversalTests extends WindowTestsBase {
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
index 1c9eed2..ce6efdf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
@@ -32,6 +32,7 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Test for {@link WindowManagerService.SettingsObserver}.
@@ -40,6 +41,7 @@
* atest WmTests:WindowManagerSettingsTests
*/
@SmallTest
+@RunWith(WindowTestRunner.class)
public class WindowManagerSettingsTests extends WindowTestsBase {
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index eed5ef5..72baedb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -222,7 +222,8 @@
final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow");
final WindowState imeWindow = createWindow(null, TYPE_INPUT_METHOD, "imeWindow");
- // Setting FLAG_NOT_FOCUSABLE prevents the window from being an IME target.
+ // Setting FLAG_NOT_FOCUSABLE without FLAG_ALT_FOCUSABLE_IM prevents the window from being
+ // an IME target.
appWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
imeWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
@@ -230,7 +231,7 @@
appWindow.setHasSurface(true);
imeWindow.setHasSurface(true);
- // Windows with FLAG_NOT_FOCUSABLE can't be IME targets
+ // Windows without flags (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM) can't be IME targets
assertFalse(appWindow.canBeImeTarget());
assertFalse(imeWindow.canBeImeTarget());
@@ -238,16 +239,10 @@
appWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
imeWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
- // Visible app window with flags FLAG_NOT_FOCUSABLE or FLAG_ALT_FOCUSABLE_IM can't be IME
- // target while an IME window can never be an IME target regardless of its visibility
- // or flags.
- assertFalse(appWindow.canBeImeTarget());
- assertFalse(imeWindow.canBeImeTarget());
-
- appWindow.mAttrs.flags &= ~FLAG_ALT_FOCUSABLE_IM;
- assertFalse(appWindow.canBeImeTarget());
- appWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE;
+ // Visible app window with flags can be IME target while an IME window can never be an IME
+ // target regardless of its visibility or flags.
assertTrue(appWindow.canBeImeTarget());
+ assertFalse(imeWindow.canBeImeTarget());
// Make windows invisible
appWindow.hideLw(false /* doAnimation */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 437b84b..22ba90b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -320,7 +320,7 @@
synchronized (mWm.mGlobalLock) {
return new ActivityTestsBase.StackBuilder(
dc.mWmService.mAtmService.mRootActivityContainer)
- .setDisplay(dc.mActivityDisplay)
+ .setDisplay(dc)
.setWindowingMode(windowingMode)
.setActivityType(activityType)
.setCreateActivity(false)
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index 4cdbea0..e6aed49 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -31,6 +31,7 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for the {@link WindowToken} class.
@@ -40,6 +41,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class WindowTokenTests extends WindowTestsBase {
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
index e3691c6..c183403 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
@@ -125,7 +125,7 @@
public void trace_dumpsWindowManagerState_whenTracing() throws Exception {
mWindowTracing.startTrace(mock(PrintWriter.class));
mWindowTracing.logState("where");
- verify(mWmMock, times(2)).writeToProtoLocked(any(), eq(WindowTraceLogLevel.TRIM));
+ verify(mWmMock, times(2)).dumpDebugLocked(any(), eq(WindowTraceLogLevel.TRIM));
}
@Test
@@ -151,7 +151,7 @@
inv.<ProtoOutputStream>getArgument(0).write(
WindowManagerTraceProto.WHERE, "TEST_WM_PROTO");
return null;
- }).when(mWmMock).writeToProtoLocked(any(), any());
+ }).when(mWmMock).dumpDebugLocked(any(), any());
mWindowTracing.logState("TEST_WHERE");
mWindowTracing.stopTrace(mock(PrintWriter.class));
diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java
index 46b261b..8fb283a 100644
--- a/services/usage/java/com/android/server/usage/IntervalStats.java
+++ b/services/usage/java/com/android/server/usage/IntervalStats.java
@@ -448,8 +448,11 @@
/**
* Parses all of the tokens to strings in the obfuscated usage stats data. This includes
* deobfuscating each of the package tokens and chooser actions and categories.
+ *
+ * @return {@code true} if any stats were omitted while deobfuscating, {@code false} otherwise.
*/
- private void deobfuscateUsageStats(PackagesTokenData packagesTokenData) {
+ private boolean deobfuscateUsageStats(PackagesTokenData packagesTokenData) {
+ boolean dataOmitted = false;
final int usageStatsSize = packageStatsObfuscated.size();
for (int statsIndex = 0; statsIndex < usageStatsSize; statsIndex++) {
final int packageToken = packageStatsObfuscated.keyAt(statsIndex);
@@ -457,6 +460,7 @@
usageStats.mPackageName = packagesTokenData.getPackageString(packageToken);
if (usageStats.mPackageName == null) {
Slog.e(TAG, "Unable to parse usage stats package " + packageToken);
+ dataOmitted = true;
continue;
}
@@ -489,14 +493,18 @@
}
packageStats.put(usageStats.mPackageName, usageStats);
}
+ return dataOmitted;
}
/**
* Parses all of the tokens to strings in the obfuscated events data. This includes
* deobfuscating the package token, along with any class, task root package/class tokens, and
* shortcut or notification channel tokens.
+ *
+ * @return {@code true} if any events were omitted while deobfuscating, {@code false} otherwise.
*/
- private void deobfuscateEvents(PackagesTokenData packagesTokenData) {
+ private boolean deobfuscateEvents(PackagesTokenData packagesTokenData) {
+ boolean dataOmitted = false;
for (int i = this.events.size() - 1; i >= 0; i--) {
final Event event = this.events.get(i);
final int packageToken = event.mPackageToken;
@@ -504,6 +512,7 @@
if (event.mPackage == null) {
Slog.e(TAG, "Unable to parse event package " + packageToken);
this.events.remove(i);
+ dataOmitted = true;
continue;
}
@@ -543,6 +552,7 @@
Slog.e(TAG, "Unable to parse shortcut " + event.mShortcutIdToken
+ " for package " + packageToken);
this.events.remove(i);
+ dataOmitted = true;
continue;
}
break;
@@ -554,21 +564,25 @@
+ event.mNotificationChannelIdToken + " for package "
+ packageToken);
this.events.remove(i);
+ dataOmitted = true;
continue;
}
break;
}
}
+ return dataOmitted;
}
/**
* Parses the obfuscated tokenized data held in this interval stats object.
*
+ * @return {@code true} if any data was omitted while deobfuscating, {@code false} otherwise.
* @hide
*/
- public void deobfuscateData(PackagesTokenData packagesTokenData) {
- deobfuscateUsageStats(packagesTokenData);
- deobfuscateEvents(packagesTokenData);
+ public boolean deobfuscateData(PackagesTokenData packagesTokenData) {
+ final boolean statsOmitted = deobfuscateUsageStats(packagesTokenData);
+ final boolean eventsOmitted = deobfuscateEvents(packagesTokenData);
+ return statsOmitted || eventsOmitted;
}
/**
diff --git a/services/usage/java/com/android/server/usage/PackagesTokenData.java b/services/usage/java/com/android/server/usage/PackagesTokenData.java
index 4bf08a4..f19abbb 100644
--- a/services/usage/java/com/android/server/usage/PackagesTokenData.java
+++ b/services/usage/java/com/android/server/usage/PackagesTokenData.java
@@ -162,15 +162,18 @@
*
* @param packageName the package to be removed
* @param timeRemoved the time stamp of when the package was removed
+ * @return the token mapped to the package removed or {@code PackagesTokenData.UNASSIGNED_TOKEN}
+ * if not mapped
*/
- public void removePackage(String packageName, long timeRemoved) {
+ public int removePackage(String packageName, long timeRemoved) {
removedPackagesMap.put(packageName, timeRemoved);
if (!packagesToTokensMap.containsKey(packageName)) {
- return;
+ return UNASSIGNED_TOKEN;
}
final int packageToken = packagesToTokensMap.get(packageName).get(packageName);
packagesToTokensMap.remove(packageName);
tokensToPackagesMap.delete(packageToken);
+ return packageToken;
}
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 27d7360..e34824c 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -29,6 +29,7 @@
import android.util.TimeUtils;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
import libcore.io.IoUtils;
@@ -52,6 +53,7 @@
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
/**
@@ -122,6 +124,7 @@
private int mCurrentVersion;
private boolean mFirstUpdate;
private boolean mNewUpdate;
+ private boolean mUpgradePerformed;
// The obfuscated packages to tokens mappings file
private final File mPackageMappingsFile;
@@ -325,6 +328,13 @@
return mNewUpdate;
}
+ /**
+ * Was an upgrade performed when this database was initialized?
+ */
+ boolean wasUpgradePerformed() {
+ return mUpgradePerformed;
+ }
+
private void checkVersionAndBuildLocked() {
int version;
String buildFingerprint;
@@ -397,6 +407,8 @@
if (mUpdateBreadcrumb.exists()) {
// Files should be up to date with current version. Clear the version update breadcrumb
mUpdateBreadcrumb.delete();
+ // update mUpgradePerformed after breadcrumb is deleted to indicate a successful upgrade
+ mUpgradePerformed = true;
}
if (mBackupsDir.exists() && !KEEP_BACKUP_DIR) {
@@ -545,12 +557,127 @@
}
}
- void onPackageRemoved(String packageName, long timeRemoved) {
+ /**
+ * Returns the token mapped to the package removed or {@code PackagesTokenData.UNASSIGNED_TOKEN}
+ * if not mapped.
+ */
+ int onPackageRemoved(String packageName, long timeRemoved) {
synchronized (mLock) {
- mPackagesTokenData.removePackage(packageName, timeRemoved);
+ final int tokenRemoved = mPackagesTokenData.removePackage(packageName, timeRemoved);
+ try {
+ writeMappingsLocked();
+ } catch (Exception e) {
+ Slog.w(TAG, "Unable to update package mappings on disk after removing token "
+ + tokenRemoved);
+ }
+ return tokenRemoved;
}
}
+ /**
+ * Reads all the usage stats data on disk and rewrites it with any data related to uninstalled
+ * packages omitted. Returns {@code true} on success, {@code false} otherwise.
+ */
+ boolean pruneUninstalledPackagesData() {
+ synchronized (mLock) {
+ for (int i = 0; i < mIntervalDirs.length; i++) {
+ final File[] files = mIntervalDirs[i].listFiles();
+ if (files == null) {
+ continue;
+ }
+ for (int j = 0; j < files.length; j++) {
+ try {
+ final IntervalStats stats = new IntervalStats();
+ final AtomicFile atomicFile = new AtomicFile(files[j]);
+ if (!readLocked(atomicFile, stats, mCurrentVersion, mPackagesTokenData)) {
+ continue; // no data was omitted when read so no need to rewrite
+ }
+ // Any data related to packages that have been removed would have failed
+ // the deobfuscation step on read so the IntervalStats object here only
+ // contains data for packages that are currently installed - all we need
+ // to do here is write the data back to disk.
+ writeLocked(atomicFile, stats, mCurrentVersion, mPackagesTokenData);
+ } catch (Exception e) {
+ Slog.e(TAG, "Failed to prune data from: " + files[j].toString());
+ return false;
+ }
+ }
+ }
+
+ try {
+ writeMappingsLocked();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to write package mappings after pruning data.");
+ return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Iterates through all the files on disk and prunes any data that belongs to packages that have
+ * been uninstalled (packages that are not in the given list).
+ * Note: this should only be called once, when there has been a database upgrade.
+ *
+ * @param installedPackages map of installed packages (package_name:package_install_time)
+ */
+ void prunePackagesDataOnUpgrade(HashMap<String, Long> installedPackages) {
+ if (ArrayUtils.isEmpty(installedPackages)) {
+ return;
+ }
+ synchronized (mLock) {
+ for (int i = 0; i < mIntervalDirs.length; i++) {
+ final File[] files = mIntervalDirs[i].listFiles();
+ if (files == null) {
+ continue;
+ }
+ for (int j = 0; j < files.length; j++) {
+ try {
+ final IntervalStats stats = new IntervalStats();
+ final AtomicFile atomicFile = new AtomicFile(files[j]);
+ readLocked(atomicFile, stats, mCurrentVersion, mPackagesTokenData);
+ if (!pruneStats(installedPackages, stats)) {
+ continue; // no stats were pruned so no need to rewrite
+ }
+ writeLocked(atomicFile, stats, mCurrentVersion, mPackagesTokenData);
+ } catch (Exception e) {
+ Slog.e(TAG, "Failed to prune data from: " + files[j].toString());
+ }
+ }
+ }
+ }
+ }
+
+ private boolean pruneStats(HashMap<String, Long> installedPackages, IntervalStats stats) {
+ boolean dataPruned = false;
+
+ // prune old package usage stats
+ for (int i = stats.packageStats.size() - 1; i >= 0; i--) {
+ final UsageStats usageStats = stats.packageStats.valueAt(i);
+ final Long timeInstalled = installedPackages.get(usageStats.mPackageName);
+ if (timeInstalled == null || timeInstalled > usageStats.mEndTimeStamp) {
+ stats.packageStats.removeAt(i);
+ dataPruned = true;
+ }
+ }
+ if (dataPruned) {
+ // ensure old stats don't linger around during the obfuscation step on write
+ stats.packageStatsObfuscated.clear();
+ }
+
+ // prune old events
+ for (int i = stats.events.size() - 1; i >= 0; i--) {
+ final UsageEvents.Event event = stats.events.get(i);
+ final Long timeInstalled = installedPackages.get(event.mPackage);
+ if (timeInstalled == null || timeInstalled > event.mTimeStamp) {
+ stats.events.remove(i);
+ dataPruned = true;
+ }
+ }
+
+ return dataPruned;
+ }
+
public void onTimeChanged(long timeDiffMillis) {
synchronized (mLock) {
StringBuilder logBuilder = new StringBuilder();
@@ -645,7 +772,6 @@
}
// filter out events
- final int eventsSize = stats.events.size();
for (int i = stats.events.size() - 1; i >= 0; i--) {
final UsageEvents.Event event = stats.events.get(i);
final Long timeRemoved = removedPackagesMap.get(event.mPackage);
@@ -942,13 +1068,17 @@
readLocked(file, statsOut, mCurrentVersion, mPackagesTokenData);
}
- private static void readLocked(AtomicFile file, IntervalStats statsOut, int version,
+ /**
+ * Returns {@code true} if any stats were omitted while reading, {@code false} otherwise.
+ */
+ private static boolean readLocked(AtomicFile file, IntervalStats statsOut, int version,
PackagesTokenData packagesTokenData) throws IOException {
+ boolean dataOmitted = false;
try {
FileInputStream in = file.openRead();
try {
statsOut.beginTime = parseBeginTime(file);
- readLocked(in, statsOut, version, packagesTokenData);
+ dataOmitted = readLocked(in, statsOut, version, packagesTokenData);
statsOut.lastTimeSaved = file.getLastModifiedTime();
} finally {
try {
@@ -961,10 +1091,15 @@
Slog.e(TAG, "UsageStatsDatabase", e);
throw e;
}
+ return dataOmitted;
}
- private static void readLocked(InputStream in, IntervalStats statsOut, int version,
+ /**
+ * Returns {@code true} if any stats were omitted while reading, {@code false} otherwise.
+ */
+ private static boolean readLocked(InputStream in, IntervalStats statsOut, int version,
PackagesTokenData packagesTokenData) throws IOException {
+ boolean dataOmitted = false;
switch (version) {
case 1:
case 2:
@@ -989,14 +1124,14 @@
} catch (IOException e) {
Slog.e(TAG, "Unable to read interval stats from proto.", e);
}
- statsOut.deobfuscateData(packagesTokenData);
+ dataOmitted = statsOut.deobfuscateData(packagesTokenData);
break;
default:
throw new RuntimeException(
"Unhandled UsageStatsDatabase version: " + Integer.toString(version)
+ " on read.");
}
-
+ return dataOmitted;
}
/**
diff --git a/services/usage/java/com/android/server/usage/UsageStatsIdleService.java b/services/usage/java/com/android/server/usage/UsageStatsIdleService.java
new file mode 100644
index 0000000..4468871
--- /dev/null
+++ b/services/usage/java/com/android/server/usage/UsageStatsIdleService.java
@@ -0,0 +1,92 @@
+/*
+ * 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.server.usage;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.app.usage.UsageStatsManagerInternal;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.PersistableBundle;
+
+import com.android.server.LocalServices;
+
+/**
+ * JobService used to do any work for UsageStats while the device is idle.
+ */
+public class UsageStatsIdleService extends JobService {
+
+ /**
+ * Base job ID for the pruning job - must be unique within the system server uid.
+ */
+ private static final int PRUNE_JOB_ID = 546357475;
+
+ private static final String USER_ID_KEY = "user_id";
+
+ static void scheduleJob(Context context, int userId) {
+ final int userJobId = PRUNE_JOB_ID + userId; // unique job id per user
+ final ComponentName component = new ComponentName(context.getPackageName(),
+ UsageStatsIdleService.class.getName());
+ final PersistableBundle bundle = new PersistableBundle();
+ bundle.putInt(USER_ID_KEY, userId);
+ final JobInfo pruneJob = new JobInfo.Builder(userJobId, component)
+ .setRequiresDeviceIdle(true)
+ .setExtras(bundle)
+ .setPersisted(true)
+ .build();
+
+ final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+ final JobInfo pendingPruneJob = jobScheduler.getPendingJob(userJobId);
+ // only schedule a new prune job if one doesn't exist already for this user
+ if (!pruneJob.equals(pendingPruneJob)) {
+ jobScheduler.cancel(userJobId); // cancel any previously scheduled prune job
+ jobScheduler.schedule(pruneJob);
+ }
+
+ }
+
+ static void cancelJob(Context context, int userId) {
+ final int userJobId = PRUNE_JOB_ID + userId; // unique job id per user
+ final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+ jobScheduler.cancel(userJobId);
+ }
+
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ final PersistableBundle bundle = params.getExtras();
+ final int userId = bundle.getInt(USER_ID_KEY, -1);
+ if (userId == -1) {
+ return false;
+ }
+
+ AsyncTask.execute(() -> {
+ final UsageStatsManagerInternal usageStatsManagerInternal = LocalServices.getService(
+ UsageStatsManagerInternal.class);
+ final boolean pruned = usageStatsManagerInternal.pruneUninstalledPackagesData(userId);
+ jobFinished(params, !pruned); // reschedule if data was not pruned
+ });
+ return true;
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ // Since the pruning job isn't a heavy job, we don't want to cancel it's execution midway.
+ return false;
+ }
+}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsProto.java b/services/usage/java/com/android/server/usage/UsageStatsProto.java
index 87e077e..932784d 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsProto.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsProto.java
@@ -410,7 +410,7 @@
final IntervalStats stats, final ConfigurationStats configStats, boolean isActive)
throws IllegalArgumentException {
final long token = proto.start(fieldId);
- configStats.mConfiguration.writeToProto(proto, IntervalStatsProto.Configuration.CONFIG);
+ configStats.mConfiguration.dumpDebug(proto, IntervalStatsProto.Configuration.CONFIG);
proto.write(IntervalStatsProto.Configuration.LAST_TIME_ACTIVE_MS,
configStats.mLastTimeActive - stats.beginTime);
proto.write(IntervalStatsProto.Configuration.TOTAL_TIME_ACTIVE_MS,
@@ -460,7 +460,7 @@
switch (event.mEventType) {
case UsageEvents.Event.CONFIGURATION_CHANGE:
if (event.mConfiguration != null) {
- event.mConfiguration.writeToProto(proto, IntervalStatsProto.Event.CONFIG);
+ event.mConfiguration.dumpDebug(proto, IntervalStatsProto.Event.CONFIG);
}
break;
case UsageEvents.Event.SHORTCUT_INVOCATION:
diff --git a/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java b/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java
index b68e04f..fe5da92 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java
@@ -355,7 +355,7 @@
private static void writeConfigStats(ProtoOutputStream proto, final long statsBeginTime,
final ConfigurationStats configStats, boolean isActive)
throws IllegalArgumentException {
- configStats.mConfiguration.writeToProto(proto,
+ configStats.mConfiguration.dumpDebug(proto,
IntervalStatsObfuscatedProto.Configuration.CONFIG);
proto.write(IntervalStatsObfuscatedProto.Configuration.LAST_TIME_ACTIVE_MS,
configStats.mLastTimeActive - statsBeginTime);
@@ -385,7 +385,7 @@
switch (event.mEventType) {
case UsageEvents.Event.CONFIGURATION_CHANGE:
if (event.mConfiguration != null) {
- event.mConfiguration.writeToProto(proto, EventObfuscatedProto.CONFIG);
+ event.mConfiguration.dumpDebug(proto, EventObfuscatedProto.CONFIG);
}
break;
case UsageEvents.Event.STANDBY_BUCKET_CHANGED:
@@ -749,7 +749,7 @@
switch (event.mEventType) {
case UsageEvents.Event.CONFIGURATION_CHANGE:
if (event.mConfiguration != null) {
- event.mConfiguration.writeToProto(proto, PendingEventProto.CONFIG);
+ event.mConfiguration.dumpDebug(proto, PendingEventProto.CONFIG);
}
break;
case UsageEvents.Event.STANDBY_BUCKET_CHANGED:
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index ba4a448..0649223 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -52,6 +52,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
@@ -99,6 +100,7 @@
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@@ -318,6 +320,8 @@
}
private void onUserUnlocked(int userId) {
+ // fetch the installed packages outside the lock so it doesn't block package manager.
+ final HashMap<String, Long> installedPackages = getInstalledPackages(userId);
synchronized (mLock) {
// Create a user unlocked event to report
final Event unlockEvent = new Event(USER_UNLOCKED, SystemClock.elapsedRealtime());
@@ -334,9 +338,10 @@
}
boolean needToFlush = !pendingEvents.isEmpty();
+ initializeUserUsageStatsServiceLocked(userId, System.currentTimeMillis(),
+ installedPackages);
mUserUnlockedStates.put(userId, true);
- final UserUsageStatsService userService = getUserDataAndInitializeIfNeededLocked(
- userId, System.currentTimeMillis());
+ final UserUsageStatsService userService = getUserUsageStatsServiceLocked(userId);
if (userService == null) {
Slog.i(TAG, "Attempted to unlock stopped or removed user " + userId);
return;
@@ -361,6 +366,29 @@
}
}
+ /**
+ * Fetches a map (package_name:install_time) of installed packages for the given user. This
+ * map contains all installed packages, including those packages which have been uninstalled
+ * with the DONT_DELETE_DATA flag.
+ * This is a helper method which should only be called when the given user's usage stats service
+ * is initialized; it performs a heavy query to package manager so do not call it otherwise.
+ * <br/>
+ * Note: DO NOT call this while holding the usage stats lock ({@code mLock}).
+ */
+ private HashMap<String, Long> getInstalledPackages(int userId) {
+ if (mPackageManager == null) {
+ return null;
+ }
+ final List<PackageInfo> installedPackages = mPackageManager.getInstalledPackagesAsUser(
+ PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
+ final HashMap<String, Long> packagesMap = new HashMap<>();
+ for (int i = installedPackages.size() - 1; i >= 0; i--) {
+ final PackageInfo packageInfo = installedPackages.get(i);
+ packagesMap.put(packageInfo.packageName, packageInfo.firstInstallTime);
+ }
+ return packagesMap;
+ }
+
private DevicePolicyManagerInternal getDpmInternal() {
if (mDpmInternal == null) {
mDpmInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
@@ -450,31 +478,42 @@
}
}
- private UserUsageStatsService getUserDataAndInitializeIfNeededLocked(int userId,
- long currentTimeMillis) {
- UserUsageStatsService service = mUserState.get(userId);
+ /**
+ * This should the be only way to fetch the usage stats service for a specific user.
+ */
+ private UserUsageStatsService getUserUsageStatsServiceLocked(int userId) {
+ final UserUsageStatsService service = mUserState.get(userId);
if (service == null) {
- final File usageStatsDir = new File(Environment.getDataSystemCeDirectory(userId),
- "usagestats");
- service = new UserUsageStatsService(getContext(), userId, usageStatsDir, this);
- if (mUserUnlockedStates.get(userId)) {
- try {
- service.init(currentTimeMillis);
- mUserState.put(userId, service);
- } catch (Exception e) {
- if (mUserManager.isUserUnlocked(userId)) {
- throw e; // rethrow exception - user is unlocked
- } else {
- Slog.w(TAG, "Attempted to initialize service for "
- + "stopped or removed user " + userId);
- return null;
- }
- }
- }
+ Slog.wtf(TAG, "Failed to fetch usage stats service for user " + userId + ". "
+ + "The user might not have been initialized yet.");
}
return service;
}
+ /**
+ * Initializes the given user's usage stats service - this should ideally only be called once,
+ * when the user is initially unlocked.
+ */
+ private void initializeUserUsageStatsServiceLocked(int userId,
+ long currentTimeMillis, HashMap<String, Long> installedPackages) {
+ final File usageStatsDir = new File(Environment.getDataSystemCeDirectory(userId),
+ "usagestats");
+ final UserUsageStatsService service = new UserUsageStatsService(getContext(), userId,
+ usageStatsDir, this);
+ try {
+ service.init(currentTimeMillis, installedPackages);
+ mUserState.put(userId, service);
+ } catch (Exception e) {
+ if (mUserManager.isUserUnlocked(userId)) {
+ Slog.w(TAG, "Failed to initialized unlocked user " + userId);
+ throw e; // rethrow the exception - user is unlocked
+ } else {
+ Slog.w(TAG, "Attempted to initialize service for stopped or removed user "
+ + userId);
+ }
+ }
+ }
+
private void migrateStatsToSystemCeIfNeededLocked(int userId) {
final File usageStatsDir = new File(Environment.getDataSystemCeDirectory(userId),
"usagestats");
@@ -694,7 +733,6 @@
return;
}
- final long timeNow = System.currentTimeMillis();
final long elapsedRealtime = SystemClock.elapsedRealtime();
if (event.mPackage != null
@@ -789,8 +827,7 @@
break;
}
- final UserUsageStatsService service =
- getUserDataAndInitializeIfNeededLocked(userId, timeNow);
+ final UserUsageStatsService service = getUserUsageStatsServiceLocked(userId);
if (service == null) {
return; // user was stopped or removed
}
@@ -841,15 +878,18 @@
mAppStandby.onUserRemoved(userId);
mAppTimeLimit.onUserRemoved(userId);
}
+ // Cancel any scheduled jobs for this user since the user is being removed.
+ UsageStatsIdleService.cancelJob(getContext(), userId);
}
/**
* Called by the Handler for message MSG_PACKAGE_REMOVED.
*/
private void onPackageRemoved(int userId, String packageName) {
+ final int tokenRemoved;
synchronized (mLock) {
final long timeRemoved = System.currentTimeMillis();
- if (!mUserUnlockedStates.get(userId, false)) {
+ if (!mUserUnlockedStates.get(userId)) {
// If user is not unlocked and a package is removed for them, we will handle it
// when the user service is initialized and package manager is queried.
return;
@@ -859,7 +899,30 @@
return;
}
- userService.onPackageRemoved(packageName, timeRemoved);
+ tokenRemoved = userService.onPackageRemoved(packageName, timeRemoved);
+ }
+
+ // Schedule a job to prune any data related to this package.
+ if (tokenRemoved != PackagesTokenData.UNASSIGNED_TOKEN) {
+ UsageStatsIdleService.scheduleJob(getContext(), userId);
+ }
+ }
+
+ /**
+ * Called by the Binder stub.
+ */
+ private boolean pruneUninstalledPackagesData(int userId) {
+ synchronized (mLock) {
+ if (!mUserUnlockedStates.get(userId)) {
+ return false; // user is no longer unlocked
+ }
+
+ final UserUsageStatsService userService = mUserState.get(userId);
+ if (userService == null) {
+ return false; // user was stopped or removed
+ }
+
+ return userService.pruneUninstalledPackagesData();
}
}
@@ -874,8 +937,7 @@
return null;
}
- final UserUsageStatsService service =
- getUserDataAndInitializeIfNeededLocked(userId, System.currentTimeMillis());
+ final UserUsageStatsService service = getUserUsageStatsServiceLocked(userId);
if (service == null) {
return null; // user was stopped or removed
}
@@ -909,8 +971,7 @@
return null;
}
- final UserUsageStatsService service =
- getUserDataAndInitializeIfNeededLocked(userId, System.currentTimeMillis());
+ final UserUsageStatsService service = getUserUsageStatsServiceLocked(userId);
if (service == null) {
return null; // user was stopped or removed
}
@@ -929,8 +990,7 @@
return null;
}
- final UserUsageStatsService service =
- getUserDataAndInitializeIfNeededLocked(userId, System.currentTimeMillis());
+ final UserUsageStatsService service = getUserUsageStatsServiceLocked(userId);
if (service == null) {
return null; // user was stopped or removed
}
@@ -949,8 +1009,7 @@
return null;
}
- final UserUsageStatsService service =
- getUserDataAndInitializeIfNeededLocked(userId, System.currentTimeMillis());
+ final UserUsageStatsService service = getUserUsageStatsServiceLocked(userId);
if (service == null) {
return null; // user was stopped or removed
}
@@ -969,8 +1028,7 @@
return null;
}
- final UserUsageStatsService service =
- getUserDataAndInitializeIfNeededLocked(userId, System.currentTimeMillis());
+ final UserUsageStatsService service = getUserUsageStatsServiceLocked(userId);
if (service == null) {
return null; // user was stopped or removed
}
@@ -2025,8 +2083,7 @@
// Check to ensure that only user 0's data is b/r for now
if (user == UserHandle.USER_SYSTEM) {
- final UserUsageStatsService userStats = getUserDataAndInitializeIfNeededLocked(
- user, System.currentTimeMillis());
+ final UserUsageStatsService userStats = getUserUsageStatsServiceLocked(user);
if (userStats == null) {
return null; // user was stopped or removed
}
@@ -2046,8 +2103,7 @@
}
if (user == UserHandle.USER_SYSTEM) {
- final UserUsageStatsService userStats = getUserDataAndInitializeIfNeededLocked(
- user, System.currentTimeMillis());
+ final UserUsageStatsService userStats = getUserUsageStatsServiceLocked(user);
if (userStats == null) {
return; // user was stopped or removed
}
@@ -2108,6 +2164,11 @@
public AppUsageLimitData getAppUsageLimit(String packageName, UserHandle user) {
return mAppTimeLimit.getAppUsageLimit(packageName, user);
}
+
+ @Override
+ public boolean pruneUninstalledPackagesData(int userId) {
+ return UsageStatsService.this.pruneUninstalledPackagesData(userId);
+ }
}
private class MyPackageMonitor extends PackageMonitor {
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index c6a5fcf..179b649 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -34,10 +34,7 @@
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManagerInternal;
import android.content.res.Configuration;
-import android.os.Process;
import android.os.SystemClock;
import android.text.format.DateUtils;
import android.util.ArrayMap;
@@ -46,8 +43,8 @@
import android.util.Slog;
import android.util.SparseIntArray;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.LocalServices;
import com.android.server.usage.UsageStatsDatabase.StatCombiner;
import java.io.File;
@@ -55,7 +52,7 @@
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.List;
/**
@@ -112,9 +109,12 @@
mSystemTimeSnapshot = System.currentTimeMillis();
}
- void init(final long currentTimeMillis) {
- readPackageMappingsLocked();
+ void init(final long currentTimeMillis, HashMap<String, Long> installedPackages) {
+ readPackageMappingsLocked(installedPackages);
mDatabase.init(currentTimeMillis);
+ if (mDatabase.wasUpgradePerformed()) {
+ mDatabase.prunePackagesDataOnUpgrade(installedPackages);
+ }
int nullCount = 0;
for (int i = 0; i < mCurrentStats.length; i++) {
@@ -170,52 +170,53 @@
persistActiveStats();
}
- void onPackageRemoved(String packageName, long timeRemoved) {
- mDatabase.onPackageRemoved(packageName, timeRemoved);
+ int onPackageRemoved(String packageName, long timeRemoved) {
+ return mDatabase.onPackageRemoved(packageName, timeRemoved);
}
- private void readPackageMappingsLocked() {
+ private void readPackageMappingsLocked(HashMap<String, Long> installedPackages) {
mDatabase.readMappingsLocked();
- cleanUpPackageMappingsLocked();
+ updatePackageMappingsLocked(installedPackages);
}
/**
- * Queries Package Manager for a list of installed packages and removes those packages from
- * mPackagesTokenData which are not installed any more.
+ * Queries Job Scheduler for any pending data prune jobs and if any exist, it updates the
+ * package mappings in memory by removing those tokens.
* This will only happen once per device boot, when the user is unlocked for the first time.
+ *
+ * @param installedPackages map of installed packages (package_name:package_install_time)
*/
- private void cleanUpPackageMappingsLocked() {
- final long timeNow = System.currentTimeMillis();
- /*
- Note (b/142501248): PackageManagerInternal#getInstalledApplications is not lightweight.
- Once its implementation is updated, or it's replaced with a better alternative, update
- the call here to use it. For now, using the heavy #getInstalledApplications is okay since
- this clean-up is only performed once every boot.
- */
- final PackageManagerInternal packageManagerInternal =
- LocalServices.getService(PackageManagerInternal.class);
- if (packageManagerInternal == null) {
+ private void updatePackageMappingsLocked(HashMap<String, Long> installedPackages) {
+ if (ArrayUtils.isEmpty(installedPackages)) {
return;
}
- final List<ApplicationInfo> installedPackages =
- packageManagerInternal.getInstalledApplications(0, mUserId, Process.SYSTEM_UID);
- // convert the package list to a set for easy look-ups
- final HashSet<String> packagesSet = new HashSet<>(installedPackages.size());
- for (int i = installedPackages.size() - 1; i >= 0; i--) {
- packagesSet.add(installedPackages.get(i).packageName);
- }
- final List<String> removedPackages = new ArrayList<>();
+
+ final long timeNow = System.currentTimeMillis();
+ final ArrayList<String> removedPackages = new ArrayList<>();
// populate list of packages that are found in the mappings but not in the installed list
for (int i = mDatabase.mPackagesTokenData.packagesToTokensMap.size() - 1; i >= 0; i--) {
- if (!packagesSet.contains(mDatabase.mPackagesTokenData.packagesToTokensMap.keyAt(i))) {
- removedPackages.add(mDatabase.mPackagesTokenData.packagesToTokensMap.keyAt(i));
+ final String packageName = mDatabase.mPackagesTokenData.packagesToTokensMap.keyAt(i);
+ if (!installedPackages.containsKey(packageName)) {
+ removedPackages.add(packageName);
}
}
+ if (removedPackages.isEmpty()) {
+ return;
+ }
- // remove packages in the mappings that are no longer installed
+ // remove packages in the mappings that are no longer installed and persist to disk
for (int i = removedPackages.size() - 1; i >= 0; i--) {
mDatabase.mPackagesTokenData.removePackage(removedPackages.get(i), timeNow);
}
+ try {
+ mDatabase.writeMappingsLocked();
+ } catch (Exception e) {
+ Slog.w(TAG, "Unable to write updated package mappings file on service initialization.");
+ }
+ }
+
+ boolean pruneUninstalledPackagesData() {
+ return mDatabase.pruneUninstalledPackagesData();
}
private void onTimeChanged(long oldTime, long newTime) {
diff --git a/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java b/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java
index 59f4d56..8263e0a 100644
--- a/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java
+++ b/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java
@@ -439,7 +439,7 @@
final ProtoOutputStream protoOutputStream =
new ProtoOutputStream(INTENT_PROTO_CHUNK_SIZE);
// Write this data out as the top-most IntentProto (i.e. it is not a sub-object).
- intent.writeToProto(protoOutputStream);
+ intent.dumpDebug(protoOutputStream);
final byte[] bytes = protoOutputStream.getBytes();
p.writeByteArray(bytes);
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index a0739c4..86ad795 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -291,7 +291,6 @@
*/
public static final int DIRECTION_OUTGOING = 1;
-
/** Call can currently be put on hold or unheld. */
public static final int CAPABILITY_HOLD = 0x00000001;
@@ -571,6 +570,7 @@
private final Bundle mIntentExtras;
private final long mCreationTimeMillis;
private final @CallDirection int mCallDirection;
+ private final @Connection.VerificationStatus int mCallerNumberVerificationStatus;
/**
* Whether the supplied capabilities supports the specified capability.
@@ -880,6 +880,15 @@
return mCallDirection;
}
+ /**
+ * Gets the verification status for the phone number of an incoming call as identified in
+ * ATIS-1000082.
+ * @return the verification status.
+ */
+ public @Connection.VerificationStatus int getCallerNumberVerificationStatus() {
+ return mCallerNumberVerificationStatus;
+ }
+
@Override
public boolean equals(Object o) {
if (o instanceof Details) {
@@ -901,7 +910,9 @@
areBundlesEqual(mExtras, d.mExtras) &&
areBundlesEqual(mIntentExtras, d.mIntentExtras) &&
Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis) &&
- Objects.equals(mCallDirection, d.mCallDirection);
+ Objects.equals(mCallDirection, d.mCallDirection) &&
+ Objects.equals(mCallerNumberVerificationStatus,
+ d.mCallerNumberVerificationStatus);
}
return false;
}
@@ -923,7 +934,8 @@
mExtras,
mIntentExtras,
mCreationTimeMillis,
- mCallDirection);
+ mCallDirection,
+ mCallerNumberVerificationStatus);
}
/** {@hide} */
@@ -944,7 +956,8 @@
Bundle extras,
Bundle intentExtras,
long creationTimeMillis,
- int callDirection) {
+ int callDirection,
+ int callerNumberVerificationStatus) {
mTelecomCallId = telecomCallId;
mHandle = handle;
mHandlePresentation = handlePresentation;
@@ -962,6 +975,7 @@
mIntentExtras = intentExtras;
mCreationTimeMillis = creationTimeMillis;
mCallDirection = callDirection;
+ mCallerNumberVerificationStatus = callerNumberVerificationStatus;
}
/** {@hide} */
@@ -983,7 +997,8 @@
parcelableCall.getExtras(),
parcelableCall.getIntentExtras(),
parcelableCall.getCreationTimeMillis(),
- parcelableCall.getCallDirection());
+ parcelableCall.getCallDirection(),
+ parcelableCall.getCallerNumberVerificationStatus());
}
@Override
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 4c22ba9..c063279 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -16,6 +16,7 @@
package android.telecom;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -35,9 +36,7 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.telephony.Annotation.RilRadioTechnology;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsStreamMediaProfile;
import android.util.ArraySet;
import android.view.Surface;
@@ -50,6 +49,8 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.nio.channels.Channels;
import java.util.ArrayList;
import java.util.Arrays;
@@ -153,6 +154,32 @@
public static final int STATE_PULLING_CALL = 7;
/**
+ * Indicates that the network could not perform verification.
+ */
+ public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0;
+
+ /**
+ * Indicates that verification by the network passed. This indicates there is a high likelihood
+ * that the call originated from a valid source.
+ */
+ public static final int VERIFICATION_STATUS_PASSED = 1;
+
+ /**
+ * Indicates that verification by the network failed. This indicates there is a high likelihood
+ * that the call did not originate from a valid source.
+ */
+ public static final int VERIFICATION_STATUS_FAILED = 2;
+
+ /**@hide*/
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "VERIFICATION_STATUS_", value = {
+ VERIFICATION_STATUS_NOT_VERIFIED,
+ VERIFICATION_STATUS_PASSED,
+ VERIFICATION_STATUS_FAILED
+ })
+ public @interface VerificationStatus {}
+
+ /**
* Connection can currently be put on hold or unheld. This is distinct from
* {@link #CAPABILITY_SUPPORT_HOLD} in that although a connection may support 'hold' most times,
* it does not at the moment support the function. This can be true while the call is in the
@@ -475,6 +502,52 @@
//**********************************************************************************************
/**
+ * Define IMS Audio Codec
+ */
+ // Current audio codec is NONE
+ public static final int AUDIO_CODEC_NONE = ImsStreamMediaProfile.AUDIO_QUALITY_NONE; // 0
+ // Current audio codec is AMR
+ public static final int AUDIO_CODEC_AMR = ImsStreamMediaProfile.AUDIO_QUALITY_AMR; // 1
+ // Current audio codec is AMR_WB
+ public static final int AUDIO_CODEC_AMR_WB = ImsStreamMediaProfile.AUDIO_QUALITY_AMR_WB; // 2
+ // Current audio codec is QCELP13K
+ public static final int AUDIO_CODEC_QCELP13K = ImsStreamMediaProfile.AUDIO_QUALITY_QCELP13K; //3
+ // Current audio codec is EVRC
+ public static final int AUDIO_CODEC_EVRC = ImsStreamMediaProfile.AUDIO_QUALITY_EVRC; // 4
+ // Current audio codec is EVRC_B
+ public static final int AUDIO_CODEC_EVRC_B = ImsStreamMediaProfile.AUDIO_QUALITY_EVRC_B; // 5
+ // Current audio codec is EVRC_WB
+ public static final int AUDIO_CODEC_EVRC_WB = ImsStreamMediaProfile.AUDIO_QUALITY_EVRC_WB; // 6
+ // Current audio codec is EVRC_NW
+ public static final int AUDIO_CODEC_EVRC_NW = ImsStreamMediaProfile.AUDIO_QUALITY_EVRC_NW; // 7
+ // Current audio codec is GSM_EFR
+ public static final int AUDIO_CODEC_GSM_EFR = ImsStreamMediaProfile.AUDIO_QUALITY_GSM_EFR; // 8
+ // Current audio codec is GSM_FR
+ public static final int AUDIO_CODEC_GSM_FR = ImsStreamMediaProfile.AUDIO_QUALITY_GSM_FR; // 9
+ // Current audio codec is GSM_HR
+ public static final int AUDIO_CODEC_GSM_HR = ImsStreamMediaProfile.AUDIO_QUALITY_GSM_HR; // 10
+ // Current audio codec is G711U
+ public static final int AUDIO_CODEC_G711U = ImsStreamMediaProfile.AUDIO_QUALITY_G711U; // 11
+ // Current audio codec is G723
+ public static final int AUDIO_CODEC_G723 = ImsStreamMediaProfile.AUDIO_QUALITY_G723; // 12
+ // Current audio codec is G711A
+ public static final int AUDIO_CODEC_G711A = ImsStreamMediaProfile.AUDIO_QUALITY_G711A; // 13
+ // Current audio codec is G722
+ public static final int AUDIO_CODEC_G722 = ImsStreamMediaProfile.AUDIO_QUALITY_G722; // 14
+ // Current audio codec is G711AB
+ public static final int AUDIO_CODEC_G711AB = ImsStreamMediaProfile.AUDIO_QUALITY_G711AB; // 15
+ // Current audio codec is G729
+ public static final int AUDIO_CODEC_G729 = ImsStreamMediaProfile.AUDIO_QUALITY_G729; // 16
+ // Current audio codec is EVS_NB
+ public static final int AUDIO_CODEC_EVS_NB = ImsStreamMediaProfile.AUDIO_QUALITY_EVS_NB; // 17
+ // Current audio codec is EVS_WB
+ public static final int AUDIO_CODEC_EVS_WB = ImsStreamMediaProfile.AUDIO_QUALITY_EVS_WB; // 18
+ // Current audio codec is EVS_SWB
+ public static final int AUDIO_CODEC_EVS_SWB = ImsStreamMediaProfile.AUDIO_QUALITY_EVS_SWB; // 19
+ // Current audio codec is EVS_FB
+ public static final int AUDIO_CODEC_EVS_FB = ImsStreamMediaProfile.AUDIO_QUALITY_EVS_FB; // 20
+
+ /**
* Connection extra key used to store the last forwarded number associated with the current
* connection. Used to communicate to the user interface that the connection was forwarded via
* the specified number.
@@ -567,6 +640,13 @@
"android.telecom.extra.IS_RTT_AUDIO_PRESENT";
/**
+ * The audio codec in use for the current {@link Connection}, if known. Valid values include
+ * {@link #AUDIO_CODEC_AMR_WB} and {@link #AUDIO_CODEC_EVS_WB}.
+ */
+ public static final String EXTRA_AUDIO_CODEC =
+ "android.telecom.extra.AUDIO_CODEC";
+
+ /**
* Connection event used to inform Telecom that it should play the on hold tone. This is used
* to play a tone when the peer puts the current call on hold. Sent to Telecom via
* {@link #sendConnectionEvent(String, Bundle)}.
@@ -1803,6 +1883,12 @@
private Set<String> mPreviousExtraKeys;
/**
+ * The verification status for an incoming call's phone number.
+ */
+ private @VerificationStatus int mCallerNumberVerificationStatus;
+
+
+ /**
* Create a new Connection.
*/
public Connection() {}
@@ -3304,4 +3390,26 @@
public void setCallDirection(@Call.Details.CallDirection int callDirection) {
mCallDirection = callDirection;
}
+
+ /**
+ * Gets the verification status for the phone number of an incoming call as identified in
+ * ATIS-1000082.
+ * @return the verification status.
+ */
+ public @VerificationStatus int getCallerNumberVerificationStatus() {
+ return mCallerNumberVerificationStatus;
+ }
+
+ /**
+ * Sets the verification status for the phone number of an incoming call as identified in
+ * ATIS-1000082.
+ * <p>
+ * This property can only be set at the time of creation of a {@link Connection} being returned
+ * by
+ * {@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}.
+ */
+ public void setCallerNumberVerificationStatus(
+ @VerificationStatus int callerNumberVerificationStatus) {
+ mCallerNumberVerificationStatus = callerNumberVerificationStatus;
+ }
}
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 812b805..3a0494e 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -1621,7 +1621,8 @@
connection.getStatusHints(),
connection.getDisconnectCause(),
createIdList(connection.getConferenceables()),
- connection.getExtras()));
+ connection.getExtras(),
+ connection.getCallerNumberVerificationStatus()));
if (isIncoming && request.shouldShowIncomingCallUi() && isSelfManaged) {
// Tell ConnectionService to show its incoming call UX.
@@ -2156,7 +2157,8 @@
emptyList,
connection.getExtras(),
conferenceId,
- connection.getCallDirection());
+ connection.getCallDirection(),
+ Connection.VERIFICATION_STATUS_NOT_VERIFIED);
mAdapter.addExistingConnection(id, parcelableConnection);
}
}
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index fdc3243..a234bb0 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -16,7 +16,6 @@
package android.telecom;
-import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.net.Uri;
import android.os.Build;
@@ -66,6 +65,7 @@
private final Bundle mExtras;
private final long mCreationTimeMillis;
private final int mCallDirection;
+ private final int mCallerNumberVerificationStatus;
public ParcelableCall(
String id,
@@ -94,7 +94,8 @@
Bundle intentExtras,
Bundle extras,
long creationTimeMillis,
- int callDirection) {
+ int callDirection,
+ int callerNumberVerificationStatus) {
mId = id;
mState = state;
mDisconnectCause = disconnectCause;
@@ -122,6 +123,7 @@
mExtras = extras;
mCreationTimeMillis = creationTimeMillis;
mCallDirection = callDirection;
+ mCallerNumberVerificationStatus = callerNumberVerificationStatus;
}
/** The unique ID of the call. */
@@ -322,6 +324,15 @@
return mCallDirection;
}
+ /**
+ * Gets the verification status for the phone number of an incoming call as identified in
+ * ATIS-1000082.
+ * @return the verification status.
+ */
+ public @Connection.VerificationStatus int getCallerNumberVerificationStatus() {
+ return mCallerNumberVerificationStatus;
+ }
+
/** Responsible for creating ParcelableCall objects for deserialized Parcels. */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public static final @android.annotation.NonNull Parcelable.Creator<ParcelableCall> CREATOR =
@@ -360,6 +371,7 @@
ParcelableRttCall rttCall = source.readParcelable(classLoader);
long creationTimeMillis = source.readLong();
int callDirection = source.readInt();
+ int callerNumberVerificationStatus = source.readInt();
return new ParcelableCall(
id,
state,
@@ -387,7 +399,8 @@
intentExtras,
extras,
creationTimeMillis,
- callDirection);
+ callDirection,
+ callerNumberVerificationStatus);
}
@Override
@@ -433,6 +446,7 @@
destination.writeParcelable(mRttCall, 0);
destination.writeLong(mCreationTimeMillis);
destination.writeInt(mCallDirection);
+ destination.writeInt(mCallerNumberVerificationStatus);
}
@Override
diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java
index 4734af6..2b9ce9b 100644
--- a/telecomm/java/android/telecom/ParcelableConnection.java
+++ b/telecomm/java/android/telecom/ParcelableConnection.java
@@ -54,6 +54,7 @@
private final Bundle mExtras;
private String mParentCallId;
private @Call.Details.CallDirection int mCallDirection;
+ private @Connection.VerificationStatus int mCallerNumberVerificationStatus;
/** @hide */
public ParcelableConnection(
@@ -77,12 +78,13 @@
List<String> conferenceableConnectionIds,
Bundle extras,
String parentCallId,
- @Call.Details.CallDirection int callDirection) {
+ @Call.Details.CallDirection int callDirection,
+ @Connection.VerificationStatus int callerNumberVerificationStatus) {
this(phoneAccount, state, capabilities, properties, supportedAudioRoutes, address,
addressPresentation, callerDisplayName, callerDisplayNamePresentation,
videoProvider, videoState, ringbackRequested, isVoipAudioMode, connectTimeMillis,
connectElapsedTimeMillis, statusHints, disconnectCause, conferenceableConnectionIds,
- extras);
+ extras, callerNumberVerificationStatus);
mParentCallId = parentCallId;
mCallDirection = callDirection;
}
@@ -107,7 +109,8 @@
StatusHints statusHints,
DisconnectCause disconnectCause,
List<String> conferenceableConnectionIds,
- Bundle extras) {
+ Bundle extras,
+ @Connection.VerificationStatus int callerNumberVerificationStatus) {
mPhoneAccount = phoneAccount;
mState = state;
mConnectionCapabilities = capabilities;
@@ -129,6 +132,7 @@
mExtras = extras;
mParentCallId = null;
mCallDirection = Call.Details.DIRECTION_UNKNOWN;
+ mCallerNumberVerificationStatus = callerNumberVerificationStatus;
}
public PhoneAccountHandle getPhoneAccount() {
@@ -227,6 +231,10 @@
return mCallDirection;
}
+ public @Connection.VerificationStatus int getCallerNumberVerificationStatus() {
+ return mCallerNumberVerificationStatus;
+ }
+
@Override
public String toString() {
return new StringBuilder()
@@ -276,6 +284,7 @@
String parentCallId = source.readString();
long connectElapsedTimeMillis = source.readLong();
int callDirection = source.readInt();
+ int callerNumberVerificationStatus = source.readInt();
return new ParcelableConnection(
phoneAccount,
@@ -298,7 +307,8 @@
conferenceableConnectionIds,
extras,
parentCallId,
- callDirection);
+ callDirection,
+ callerNumberVerificationStatus);
}
@Override
@@ -338,5 +348,6 @@
destination.writeString(mParentCallId);
destination.writeLong(mConnectElapsedTimeMillis);
destination.writeInt(mCallDirection);
+ destination.writeInt(mCallerNumberVerificationStatus);
}
}
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 72f758e..f89bbc7 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -1,6 +1,7 @@
package android.telephony;
import android.annotation.IntDef;
+import android.telecom.Connection;
import android.telephony.data.ApnSetting;
import java.lang.annotation.Retention;
@@ -509,4 +510,30 @@
ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA,
ServiceState.RIL_RADIO_TECHNOLOGY_NR})
public @interface RilRadioTechnology {}
+
+ @IntDef({
+ Connection.AUDIO_CODEC_NONE,
+ Connection.AUDIO_CODEC_AMR,
+ Connection.AUDIO_CODEC_AMR_WB,
+ Connection.AUDIO_CODEC_QCELP13K,
+ Connection.AUDIO_CODEC_EVRC,
+ Connection.AUDIO_CODEC_EVRC_B,
+ Connection.AUDIO_CODEC_EVRC_WB,
+ Connection.AUDIO_CODEC_EVRC_NW,
+ Connection.AUDIO_CODEC_GSM_EFR,
+ Connection.AUDIO_CODEC_GSM_FR,
+ Connection.AUDIO_CODEC_G711U,
+ Connection.AUDIO_CODEC_G723,
+ Connection.AUDIO_CODEC_G711A,
+ Connection.AUDIO_CODEC_G722,
+ Connection.AUDIO_CODEC_G711AB,
+ Connection.AUDIO_CODEC_G729,
+ Connection.AUDIO_CODEC_EVS_NB,
+ Connection.AUDIO_CODEC_EVS_WB,
+ Connection.AUDIO_CODEC_EVS_SWB,
+ Connection.AUDIO_CODEC_EVS_FB
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ImsAudioCodec {
+ }
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 98d7661..1b86c09 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -100,6 +100,16 @@
KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool";
/**
+ * Boolean indicating the Supplementary Services(SS) is disable when airplane mode on in the
+ * Call Settings menu.
+ * {@code true}: SS is disable when airplane mode on.
+ * {@code false}: SS is enable when airplane mode on.
+ * The default value for this key is {@code false}
+ */
+ public static final String KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL =
+ "disable_supplementary_services_in_airplane_mode_bool";
+
+ /**
* Boolean indicating if the "Call forwarding" item is visible in the Call Settings menu.
* true means visible. false means gone.
* @hide
@@ -3439,6 +3449,7 @@
sDefaults.putBoolean(KEY_CALL_FORWARDING_WHEN_UNREACHABLE_SUPPORTED_BOOL, true);
sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL, true);
sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL, true);
+ sDefaults.putBoolean(KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL, false);
sDefaults.putBoolean(KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL, false);
sDefaults.putBoolean(KEY_MDN_IS_ADDITIONAL_VOICEMAIL_NUMBER_BOOL, false);
sDefaults.putBoolean(KEY_OPERATOR_SELECTION_EXPAND_BOOL, true);
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 9ace86c..d2c8517 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -278,12 +278,9 @@
*/
public static final int UNKNOWN_ID = -1;
- private String mVoiceOperatorAlphaLong;
- private String mVoiceOperatorAlphaShort;
- private String mVoiceOperatorNumeric;
- private String mDataOperatorAlphaLong;
- private String mDataOperatorAlphaShort;
- private String mDataOperatorNumeric;
+ private String mOperatorAlphaLong;
+ private String mOperatorAlphaShort;
+ private String mOperatorNumeric;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private boolean mIsManualNetworkSelection;
@@ -379,12 +376,9 @@
protected void copyFrom(ServiceState s) {
mVoiceRegState = s.mVoiceRegState;
mDataRegState = s.mDataRegState;
- mVoiceOperatorAlphaLong = s.mVoiceOperatorAlphaLong;
- mVoiceOperatorAlphaShort = s.mVoiceOperatorAlphaShort;
- mVoiceOperatorNumeric = s.mVoiceOperatorNumeric;
- mDataOperatorAlphaLong = s.mDataOperatorAlphaLong;
- mDataOperatorAlphaShort = s.mDataOperatorAlphaShort;
- mDataOperatorNumeric = s.mDataOperatorNumeric;
+ mOperatorAlphaLong = s.mOperatorAlphaLong;
+ mOperatorAlphaShort = s.mOperatorAlphaShort;
+ mOperatorNumeric = s.mOperatorNumeric;
mIsManualNetworkSelection = s.mIsManualNetworkSelection;
mCssIndicator = s.mCssIndicator;
mNetworkId = s.mNetworkId;
@@ -418,12 +412,9 @@
public ServiceState(Parcel in) {
mVoiceRegState = in.readInt();
mDataRegState = in.readInt();
- mVoiceOperatorAlphaLong = in.readString();
- mVoiceOperatorAlphaShort = in.readString();
- mVoiceOperatorNumeric = in.readString();
- mDataOperatorAlphaLong = in.readString();
- mDataOperatorAlphaShort = in.readString();
- mDataOperatorNumeric = in.readString();
+ mOperatorAlphaLong = in.readString();
+ mOperatorAlphaShort = in.readString();
+ mOperatorNumeric = in.readString();
mIsManualNetworkSelection = in.readInt() != 0;
mCssIndicator = (in.readInt() != 0);
mNetworkId = in.readInt();
@@ -448,12 +439,9 @@
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mVoiceRegState);
out.writeInt(mDataRegState);
- out.writeString(mVoiceOperatorAlphaLong);
- out.writeString(mVoiceOperatorAlphaShort);
- out.writeString(mVoiceOperatorNumeric);
- out.writeString(mDataOperatorAlphaLong);
- out.writeString(mDataOperatorAlphaShort);
- out.writeString(mDataOperatorNumeric);
+ out.writeString(mOperatorAlphaLong);
+ out.writeString(mOperatorAlphaShort);
+ out.writeString(mOperatorNumeric);
out.writeInt(mIsManualNetworkSelection ? 1 : 0);
out.writeInt(mCssIndicator ? 1 : 0);
out.writeInt(mNetworkId);
@@ -691,7 +679,7 @@
* @return long name of operator, null if unregistered or unknown
*/
public String getOperatorAlphaLong() {
- return mVoiceOperatorAlphaLong;
+ return mOperatorAlphaLong;
}
/**
@@ -699,18 +687,10 @@
* @return long name of operator
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "Use {@link #getOperatorAlphaLong} instead.")
public String getVoiceOperatorAlphaLong() {
- return mVoiceOperatorAlphaLong;
- }
-
- /**
- * Get current registered data network operator name in long alphanumeric format.
- * @return long name of voice operator
- * @hide
- */
- public String getDataOperatorAlphaLong() {
- return mDataOperatorAlphaLong;
+ return mOperatorAlphaLong;
}
/**
@@ -721,7 +701,7 @@
* @return short name of operator, null if unregistered or unknown
*/
public String getOperatorAlphaShort() {
- return mVoiceOperatorAlphaShort;
+ return mOperatorAlphaShort;
}
/**
@@ -729,9 +709,10 @@
* @return short name of operator, null if unregistered or unknown
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "Use {@link #getOperatorAlphaShort} instead.")
public String getVoiceOperatorAlphaShort() {
- return mVoiceOperatorAlphaShort;
+ return mOperatorAlphaShort;
}
/**
@@ -739,9 +720,10 @@
* @return short name of operator, null if unregistered or unknown
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "Use {@link #getOperatorAlphaShort} instead.")
public String getDataOperatorAlphaShort() {
- return mDataOperatorAlphaShort;
+ return mOperatorAlphaShort;
}
/**
@@ -755,11 +737,11 @@
* @hide
*/
public String getOperatorAlpha() {
- if (TextUtils.isEmpty(mVoiceOperatorAlphaLong)) {
- return mVoiceOperatorAlphaShort;
+ if (TextUtils.isEmpty(mOperatorAlphaLong)) {
+ return mOperatorAlphaShort;
}
- return mVoiceOperatorAlphaLong;
+ return mOperatorAlphaLong;
}
/**
@@ -775,7 +757,7 @@
* {@link com.android.internal.telephony.MccTable#countryCodeForMcc(int)}.
*/
public String getOperatorNumeric() {
- return mVoiceOperatorNumeric;
+ return mOperatorNumeric;
}
/**
@@ -785,7 +767,7 @@
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public String getVoiceOperatorNumeric() {
- return mVoiceOperatorNumeric;
+ return mOperatorNumeric;
}
/**
@@ -793,9 +775,10 @@
* @return numeric format of operator, null if unregistered or unknown
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "Use {@link #getOperatorNumeric} instead.")
public String getDataOperatorNumeric() {
- return mDataOperatorNumeric;
+ return mOperatorNumeric;
}
/**
@@ -815,12 +798,9 @@
mDataRegState,
mChannelNumber,
Arrays.hashCode(mCellBandwidths),
- mVoiceOperatorAlphaLong,
- mVoiceOperatorAlphaShort,
- mVoiceOperatorNumeric,
- mDataOperatorAlphaLong,
- mDataOperatorAlphaShort,
- mDataOperatorNumeric,
+ mOperatorAlphaLong,
+ mOperatorAlphaShort,
+ mOperatorNumeric,
mIsManualNetworkSelection,
mCssIndicator,
mNetworkId,
@@ -850,12 +830,9 @@
&& mIsManualNetworkSelection == s.mIsManualNetworkSelection
&& mChannelNumber == s.mChannelNumber
&& Arrays.equals(mCellBandwidths, s.mCellBandwidths)
- && equalsHandlesNulls(mVoiceOperatorAlphaLong, s.mVoiceOperatorAlphaLong)
- && equalsHandlesNulls(mVoiceOperatorAlphaShort, s.mVoiceOperatorAlphaShort)
- && equalsHandlesNulls(mVoiceOperatorNumeric, s.mVoiceOperatorNumeric)
- && equalsHandlesNulls(mDataOperatorAlphaLong, s.mDataOperatorAlphaLong)
- && equalsHandlesNulls(mDataOperatorAlphaShort, s.mDataOperatorAlphaShort)
- && equalsHandlesNulls(mDataOperatorNumeric, s.mDataOperatorNumeric)
+ && equalsHandlesNulls(mOperatorAlphaLong, s.mOperatorAlphaLong)
+ && equalsHandlesNulls(mOperatorAlphaShort, s.mOperatorAlphaShort)
+ && equalsHandlesNulls(mOperatorNumeric, s.mOperatorNumeric)
&& equalsHandlesNulls(mCssIndicator, s.mCssIndicator)
&& equalsHandlesNulls(mNetworkId, s.mNetworkId)
&& equalsHandlesNulls(mSystemId, s.mSystemId)
@@ -1007,10 +984,8 @@
.append(", mChannelNumber=").append(mChannelNumber)
.append(", duplexMode()=").append(getDuplexMode())
.append(", mCellBandwidths=").append(Arrays.toString(mCellBandwidths))
- .append(", mVoiceOperatorAlphaLong=").append(mVoiceOperatorAlphaLong)
- .append(", mVoiceOperatorAlphaShort=").append(mVoiceOperatorAlphaShort)
- .append(", mDataOperatorAlphaLong=").append(mDataOperatorAlphaLong)
- .append(", mDataOperatorAlphaShort=").append(mDataOperatorAlphaShort)
+ .append(", mOperatorAlphaLong=").append(mOperatorAlphaLong)
+ .append(", mOperatorAlphaShort=").append(mOperatorAlphaShort)
.append(", isManualNetworkSelection=").append(mIsManualNetworkSelection)
.append(mIsManualNetworkSelection ? "(manual)" : "(automatic)")
.append(", getRilVoiceRadioTechnology=").append(getRilVoiceRadioTechnology())
@@ -1040,12 +1015,9 @@
mDataRegState = STATE_OUT_OF_SERVICE;
mChannelNumber = -1;
mCellBandwidths = new int[0];
- mVoiceOperatorAlphaLong = null;
- mVoiceOperatorAlphaShort = null;
- mVoiceOperatorNumeric = null;
- mDataOperatorAlphaLong = null;
- mDataOperatorAlphaShort = null;
- mDataOperatorNumeric = null;
+ mOperatorAlphaLong = null;
+ mOperatorAlphaShort = null;
+ mOperatorNumeric = null;
mIsManualNetworkSelection = false;
mCssIndicator = false;
mNetworkId = -1;
@@ -1204,26 +1176,9 @@
}
public void setOperatorName(String longName, String shortName, String numeric) {
- mVoiceOperatorAlphaLong = longName;
- mVoiceOperatorAlphaShort = shortName;
- mVoiceOperatorNumeric = numeric;
- mDataOperatorAlphaLong = longName;
- mDataOperatorAlphaShort = shortName;
- mDataOperatorNumeric = numeric;
- }
-
- /** @hide */
- public void setVoiceOperatorName(String longName, String shortName, String numeric) {
- mVoiceOperatorAlphaLong = longName;
- mVoiceOperatorAlphaShort = shortName;
- mVoiceOperatorNumeric = numeric;
- }
-
- /** @hide */
- public void setDataOperatorName(String longName, String shortName, String numeric) {
- mDataOperatorAlphaLong = longName;
- mDataOperatorAlphaShort = shortName;
- mDataOperatorNumeric = numeric;
+ mOperatorAlphaLong = longName;
+ mOperatorAlphaShort = shortName;
+ mOperatorNumeric = numeric;
}
/**
@@ -1233,19 +1188,8 @@
* @hide
*/
@UnsupportedAppUsage
- public void setOperatorAlphaLong(String longName) {
- mVoiceOperatorAlphaLong = longName;
- mDataOperatorAlphaLong = longName;
- }
-
- /** @hide */
- public void setVoiceOperatorAlphaLong(String longName) {
- mVoiceOperatorAlphaLong = longName;
- }
-
- /** @hide */
- public void setDataOperatorAlphaLong(String longName) {
- mDataOperatorAlphaLong = longName;
+ public void setOperatorAlphaLong(@Nullable String longName) {
+ mOperatorAlphaLong = longName;
}
public void setIsManualSelection(boolean isManual) {
@@ -1293,12 +1237,12 @@
m.putInt("dataRegState", mDataRegState);
m.putInt("dataRoamingType", getDataRoamingType());
m.putInt("voiceRoamingType", getVoiceRoamingType());
- m.putString("operator-alpha-long", mVoiceOperatorAlphaLong);
- m.putString("operator-alpha-short", mVoiceOperatorAlphaShort);
- m.putString("operator-numeric", mVoiceOperatorNumeric);
- m.putString("data-operator-alpha-long", mDataOperatorAlphaLong);
- m.putString("data-operator-alpha-short", mDataOperatorAlphaShort);
- m.putString("data-operator-numeric", mDataOperatorNumeric);
+ m.putString("operator-alpha-long", mOperatorAlphaLong);
+ m.putString("operator-alpha-short", mOperatorAlphaShort);
+ m.putString("operator-numeric", mOperatorNumeric);
+ m.putString("data-operator-alpha-long", mOperatorAlphaLong);
+ m.putString("data-operator-alpha-short", mOperatorAlphaShort);
+ m.putString("data-operator-numeric", mOperatorNumeric);
m.putBoolean("manual", mIsManualNetworkSelection);
m.putInt("radioTechnology", getRilVoiceRadioTechnology());
m.putInt("dataRadioTechnology", getRadioTechnology());
@@ -1933,12 +1877,9 @@
}
if (!removeCoarseLocation) return state;
- state.mDataOperatorAlphaLong = null;
- state.mDataOperatorAlphaShort = null;
- state.mDataOperatorNumeric = null;
- state.mVoiceOperatorAlphaLong = null;
- state.mVoiceOperatorAlphaShort = null;
- state.mVoiceOperatorNumeric = null;
+ state.mOperatorAlphaLong = null;
+ state.mOperatorAlphaShort = null;
+ state.mOperatorNumeric = null;
return state;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index fc26122..e3981f6 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4723,17 +4723,6 @@
}
/**
- * Sim activation type: voice
- * @hide
- */
- public static final int SIM_ACTIVATION_TYPE_VOICE = 0;
- /**
- * Sim activation type: data
- * @hide
- */
- public static final int SIM_ACTIVATION_TYPE_DATA = 1;
-
- /**
* Initial SIM activation state, unknown. Not set by any carrier apps.
* @hide
*/
@@ -8172,17 +8161,25 @@
return Collections.EMPTY_LIST;
}
- /** @hide */
- public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
+ /**
+ * Get the names of packages with carrier privileges for all the active subscriptions.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @NonNull
+ public List<String> getCarrierPrivilegedPackagesForAllActiveSubscriptions() {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
return telephony.getPackagesWithCarrierPrivilegesForAllPhones();
}
} catch (RemoteException ex) {
- Rlog.e(TAG, "getPackagesWithCarrierPrivilegesForAllPhones RemoteException", ex);
+ Rlog.e(TAG, "getCarrierPrivilegedPackagesForAllActiveSubscriptions RemoteException",
+ ex);
} catch (NullPointerException ex) {
- Rlog.e(TAG, "getPackagesWithCarrierPrivilegesForAllPhones NPE", ex);
+ Rlog.e(TAG, "getCarrierPrivilegedPackagesForAllActiveSubscriptions NPE", ex);
}
return Collections.EMPTY_LIST;
}
diff --git a/tools/processors/unsupportedappusage/Android.bp b/tools/processors/unsupportedappusage/Android.bp
deleted file mode 100644
index 1e96234..0000000
--- a/tools/processors/unsupportedappusage/Android.bp
+++ /dev/null
@@ -1,34 +0,0 @@
-
-java_library_host {
- name: "unsupportedappusage-annotation-processor-lib",
- srcs: [
- "src/**/*.java",
- ],
- static_libs: [
- "guava",
- "unsupportedappusage-annotation"
- ],
- openjdk9: {
- javacflags: [
- "--add-modules=jdk.compiler",
- "--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
- "--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED",
- "--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
- "--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
- ],
- },
-}
-
-java_plugin {
- name: "unsupportedappusage-annotation-processor",
- processor_class: "android.processor.unsupportedappusage.UnsupportedAppUsageProcessor",
-
- java_resources: [
- "META-INF/**/*",
- ],
- static_libs: [
- "unsupportedappusage-annotation-processor-lib"
- ],
-
- use_tools_jar: true,
-}
diff --git a/tools/processors/unsupportedappusage/META-INF/services/javax.annotation.processing.Processor b/tools/processors/unsupportedappusage/META-INF/services/javax.annotation.processing.Processor
deleted file mode 100644
index 4a969d3..0000000
--- a/tools/processors/unsupportedappusage/META-INF/services/javax.annotation.processing.Processor
+++ /dev/null
@@ -1 +0,0 @@
-android.processor.unsupportedappusage.UnsupportedAppUsageProcessor
diff --git a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java
deleted file mode 100644
index 65fc733..0000000
--- a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.processor.unsupportedappusage;
-
-import static javax.lang.model.element.ElementKind.PACKAGE;
-import static javax.tools.Diagnostic.Kind.ERROR;
-import static javax.tools.Diagnostic.Kind.WARNING;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMap;
-import com.sun.tools.javac.code.Type;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.processing.Messager;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Builds a dex signature for a given method or field.
- */
-public class SignatureBuilder {
-
- private static final Map<TypeKind, String> TYPE_MAP = ImmutableMap.<TypeKind, String>builder()
- .put(TypeKind.BOOLEAN, "Z")
- .put(TypeKind.BYTE, "B")
- .put(TypeKind.CHAR, "C")
- .put(TypeKind.DOUBLE, "D")
- .put(TypeKind.FLOAT, "F")
- .put(TypeKind.INT, "I")
- .put(TypeKind.LONG, "J")
- .put(TypeKind.SHORT, "S")
- .put(TypeKind.VOID, "V")
- .build();
-
- private final Messager mMessager;
-
- /**
- * Exception used internally when we can't build a signature. Whenever this is thrown, an error
- * will also be written to the Messager.
- */
- private class SignatureBuilderException extends Exception {
- public SignatureBuilderException(String message) {
- super(message);
- }
-
- public void report(Element offendingElement) {
- mMessager.printMessage(ERROR, getMessage(), offendingElement);
- }
- }
-
- public SignatureBuilder(Messager messager) {
- mMessager = messager;
- }
-
- /**
- * Returns a list of enclosing elements for the given element, with the package first, and
- * excluding the element itself.
- */
- private List<Element> getEnclosingElements(Element e) {
- List<Element> enclosing = new ArrayList<>();
- e = e.getEnclosingElement(); // don't include the element itself.
- while (e != null) {
- enclosing.add(e);
- e = e.getEnclosingElement();
- }
- Collections.reverse(enclosing);
- return enclosing;
- }
-
- /**
- * Get the dex signature for a clazz, in format "Lpackage/name/Outer$Inner;"
- */
- private String getClassSignature(TypeElement clazz) {
- StringBuilder sb = new StringBuilder("L");
- for (Element enclosing : getEnclosingElements(clazz)) {
- switch (enclosing.getKind()) {
- case MODULE:
- // ignore this.
- break;
- case PACKAGE:
- sb.append(((PackageElement) enclosing)
- .getQualifiedName()
- .toString()
- .replace('.', '/'));
- sb.append('/');
- break;
- default:
- sb.append(enclosing.getSimpleName()).append('$');
- break;
- }
-
- }
- return sb
- .append(clazz.getSimpleName())
- .append(";")
- .toString();
- }
-
- /**
- * Returns the type signature for a given type. For primitive types, a single character.
- * For classes, the class signature. For arrays, a "[" preceeding the component type.
- */
- private String getTypeSignature(TypeMirror type) throws SignatureBuilderException {
- String sig = TYPE_MAP.get(type.getKind());
- if (sig != null) {
- return sig;
- }
- switch (type.getKind()) {
- case ARRAY:
- return "[" + getTypeSignature(((ArrayType) type).getComponentType());
- case DECLARED:
- Element declaring = ((DeclaredType) type).asElement();
- if (!(declaring instanceof TypeElement)) {
- throw new SignatureBuilderException(
- "Can't handle declared type of kind " + declaring.getKind());
- }
- return getClassSignature((TypeElement) declaring);
- case TYPEVAR:
- Type.TypeVar typeVar = (Type.TypeVar) type;
- if (typeVar.getLowerBound().getKind() != TypeKind.NULL) {
- return getTypeSignature(typeVar.getLowerBound());
- } else if (typeVar.getUpperBound().getKind() != TypeKind.NULL) {
- return getTypeSignature(typeVar.getUpperBound());
- } else {
- throw new SignatureBuilderException("Can't handle typevar with no bound");
- }
-
- default:
- throw new SignatureBuilderException("Can't handle type of kind " + type.getKind());
- }
- }
-
- /**
- * Get the signature for an executable, either a method or a constructor.
- *
- * @param name "<init>" for constructor, else the method name
- * @param method The executable element in question.
- */
- private String getExecutableSignature(CharSequence name, ExecutableElement method)
- throws SignatureBuilderException {
- StringBuilder sig = new StringBuilder();
- sig.append(getClassSignature((TypeElement) method.getEnclosingElement()))
- .append("->")
- .append(name)
- .append("(");
- for (VariableElement param : method.getParameters()) {
- sig.append(getTypeSignature(param.asType()));
- }
- sig.append(")")
- .append(getTypeSignature(method.getReturnType()));
- return sig.toString();
- }
-
- private String buildMethodSignature(ExecutableElement method) throws SignatureBuilderException {
- return getExecutableSignature(method.getSimpleName(), method);
- }
-
- private String buildConstructorSignature(ExecutableElement cons)
- throws SignatureBuilderException {
- return getExecutableSignature("<init>", cons);
- }
-
- private String buildFieldSignature(VariableElement field) throws SignatureBuilderException {
- StringBuilder sig = new StringBuilder();
- sig.append(getClassSignature((TypeElement) field.getEnclosingElement()))
- .append("->")
- .append(field.getSimpleName())
- .append(":")
- .append(getTypeSignature(field.asType()))
- ;
- return sig.toString();
- }
-
- /**
- * Creates the signature for an annotated element.
- *
- * @param annotationType type of annotation being processed.
- * @param element element for which we want to create a signature.
- */
- public String buildSignature(Class<? extends Annotation> annotationType, Element element) {
- try {
- String signature;
- switch (element.getKind()) {
- case METHOD:
- signature = buildMethodSignature((ExecutableElement) element);
- break;
- case CONSTRUCTOR:
- signature = buildConstructorSignature((ExecutableElement) element);
- break;
- case FIELD:
- signature = buildFieldSignature((VariableElement) element);
- break;
- default:
- return null;
- }
- // Obtain annotation objects
- Annotation annotation = element.getAnnotation(annotationType);
- if (annotation == null) {
- throw new IllegalStateException(
- "Element doesn't have any UnsupportedAppUsage annotation");
- }
- try {
- Method expectedSignatureMethod = annotationType.getMethod("expectedSignature");
- // If we have an expected signature on the annotation, warn if it doesn't match.
- String expectedSignature = expectedSignatureMethod.invoke(annotation).toString();
- if (!Strings.isNullOrEmpty(expectedSignature)) {
- if (!signature.equals(expectedSignature)) {
- mMessager.printMessage(
- WARNING,
- String.format(
- "Expected signature doesn't match generated signature.\n"
- + " Expected: %s\n Generated: %s",
- expectedSignature, signature),
- element);
- }
- }
- return signature;
- } catch (NoSuchMethodException e) {
- throw new IllegalStateException(
- "Annotation type does not have expectedSignature parameter", e);
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new IllegalStateException(
- "Could not get expectedSignature parameter for annotation", e);
- }
- } catch (SignatureBuilderException problem) {
- problem.report(element);
- return null;
- }
- }
-}
diff --git a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SourcePosition.java b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SourcePosition.java
deleted file mode 100644
index 4ae093c..0000000
--- a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SourcePosition.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.processor.unsupportedappusage;
-
-/**
- * Represents a source position within a source file
- */
-public class SourcePosition {
- public final String filename;
- public final int startLine;
- public final int startCol;
- public final int endLine;
- public final int endCol;
-
- public SourcePosition(String filename, int startLine, int startCol, int endLine, int endCol) {
- this.filename = filename;
- this.startLine = startLine;
- this.startCol = startCol;
- this.endLine = endLine;
- this.endCol = endCol;
- }
-}
diff --git a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java
deleted file mode 100644
index ca2c275..0000000
--- a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.processor.unsupportedappusage;
-
-import static javax.tools.StandardLocation.CLASS_OUTPUT;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableSet;
-import com.sun.tools.javac.model.JavacElements;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.util.Pair;
-import com.sun.tools.javac.util.Position;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.lang.annotation.Annotation;
-import java.net.URLEncoder;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.stream.Stream;
-
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.RoundEnvironment;
-import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.tools.Diagnostic;
-
-/**
- * Annotation processor for {@link UnsupportedAppUsage} annotations.
- *
- * This processor currently outputs a CSV file with a mapping of dex signatures to corresponding
- * source positions.
- *
- * This is used for automating updates to the annotations themselves.
- */
-@SupportedAnnotationTypes({"android.annotation.UnsupportedAppUsage",
- "dalvik.annotation.compat.UnsupportedAppUsage"
-})
-public class UnsupportedAppUsageProcessor extends AbstractProcessor {
-
- // Package name for writing output. Output will be written to the "class output" location within
- // this package.
- private static final String PACKAGE = "unsupportedappusage";
- private static final String INDEX_CSV = "unsupportedappusage_index.csv";
-
- private static final ImmutableSet<Class<? extends Annotation>> SUPPORTED_ANNOTATIONS =
- ImmutableSet.of(android.annotation.UnsupportedAppUsage.class,
- dalvik.annotation.compat.UnsupportedAppUsage.class);
- private static final ImmutableSet<String> SUPPORTED_ANNOTATION_NAMES =
- SUPPORTED_ANNOTATIONS.stream().map(annotation -> annotation.getCanonicalName()).collect(
- ImmutableSet.toImmutableSet());
- private static final String OVERRIDE_SOURCE_POSITION_PROPERTY = "overrideSourcePosition";
-
- @Override
- public SourceVersion getSupportedSourceVersion() {
- return SourceVersion.latest();
- }
-
- /**
- * Write the contents of a stream to a text file, with one line per item.
- */
- private void writeToFile(String name,
- String headerLine,
- Stream<?> contents) throws IOException {
- PrintStream out = new PrintStream(processingEnv.getFiler().createResource(
- CLASS_OUTPUT,
- PACKAGE,
- name)
- .openOutputStream());
- out.println(headerLine);
- contents.forEach(o -> out.println(o));
- if (out.checkError()) {
- throw new IOException("Error when writing to " + name);
- }
- out.close();
- }
-
- /**
- * Find the annotation mirror for the @UnsupportedAppUsage annotation on the given element.
- */
- private AnnotationMirror getUnsupportedAppUsageAnnotationMirror(Element e) {
- for (AnnotationMirror m : e.getAnnotationMirrors()) {
- TypeElement type = (TypeElement) m.getAnnotationType().asElement();
- if (SUPPORTED_ANNOTATION_NAMES.contains(type.getQualifiedName().toString())) {
- return m;
- }
- }
- return null;
- }
-
- /**
- * Returns a CSV header line for the columns returned by
- * {@link #getAnnotationIndex(String, Element)}.
- */
- private String getCsvHeaders() {
- return Joiner.on(',').join(
- "signature",
- "file",
- "startline",
- "startcol",
- "endline",
- "endcol",
- "properties"
- );
- }
-
- private String encodeAnnotationProperties(AnnotationMirror annotation) {
- StringBuilder sb = new StringBuilder();
- for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> e
- : annotation.getElementValues().entrySet()) {
- if (e.getKey().getSimpleName().toString().equals(OVERRIDE_SOURCE_POSITION_PROPERTY)) {
- continue;
- }
- if (sb.length() > 0) {
- sb.append("&");
- }
- sb.append(e.getKey().getSimpleName())
- .append("=")
- .append(URLEncoder.encode(e.getValue().toString()));
- }
- return sb.toString();
- }
-
- private SourcePosition getSourcePositionOverride(
- Element annotatedElement, AnnotationMirror annotation) {
- for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> e
- : annotation.getElementValues().entrySet()) {
- if (e.getKey().getSimpleName().toString().equals(OVERRIDE_SOURCE_POSITION_PROPERTY)) {
- String[] position = e.getValue().getValue().toString().split(":");
- if (position.length != 5) {
- processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format(
- "Expected %s to have format file:startLine:startCol:endLine:endCol",
- OVERRIDE_SOURCE_POSITION_PROPERTY), annotatedElement, annotation);
- return null;
- }
- try {
- return new SourcePosition(position[0], Integer.parseInt(position[1]),
- Integer.parseInt(position[2]), Integer.parseInt(position[3]),
- Integer.parseInt(position[4]));
- } catch (NumberFormatException nfe) {
- processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format(
- "Expected %s to have format file:startLine:startCol:endLine:endCol; "
- + "error parsing integer: %s", OVERRIDE_SOURCE_POSITION_PROPERTY,
- nfe.getMessage()), annotatedElement, annotation);
- return null;
- }
- }
- }
- return null;
- }
-
- /**
- * Maps an annotated element to the source position of the @UnsupportedAppUsage annotation
- * attached to it. It returns CSV in the format:
- * dex-signature,filename,start-line,start-col,end-line,end-col
- *
- * The positions refer to the annotation itself, *not* the annotated member. This can therefore
- * be used to read just the annotation from the file, and to perform in-place edits on it.
- *
- * @param signature the dex signature for the element.
- * @param annotatedElement The annotated element
- * @return A single line of CSV text
- */
- private String getAnnotationIndex(String signature, Element annotatedElement) {
- JavacElements javacElem = (JavacElements) processingEnv.getElementUtils();
- AnnotationMirror unsupportedAppUsage =
- getUnsupportedAppUsageAnnotationMirror(annotatedElement);
- SourcePosition position = getSourcePositionOverride(annotatedElement, unsupportedAppUsage);
- if (position == null) {
- Pair<JCTree, JCTree.JCCompilationUnit> pair =
- javacElem.getTreeAndTopLevel(annotatedElement, unsupportedAppUsage, null);
- Position.LineMap lines = pair.snd.lineMap;
- position = new SourcePosition(
- pair.snd.getSourceFile().getName(),
- lines.getLineNumber(pair.fst.pos().getStartPosition()),
- lines.getColumnNumber(pair.fst.pos().getStartPosition()),
- lines.getLineNumber(pair.fst.pos().getEndPosition(pair.snd.endPositions)),
- lines.getColumnNumber(pair.fst.pos().getEndPosition(pair.snd.endPositions)));
- }
- return Joiner.on(",").join(
- signature,
- position.filename,
- position.startLine,
- position.startCol,
- position.endLine,
- position.endCol,
- encodeAnnotationProperties(unsupportedAppUsage));
- }
-
- /**
- * This is the main entry point in the processor, called by the compiler.
- */
- @Override
- public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
- Map<String, Element> signatureMap = new TreeMap<>();
- SignatureBuilder sb = new SignatureBuilder(processingEnv.getMessager());
- for (Class<? extends Annotation> supportedAnnotation : SUPPORTED_ANNOTATIONS) {
- Set<? extends Element> annotated = roundEnv.getElementsAnnotatedWith(
- supportedAnnotation);
- if (annotated.size() == 0) {
- continue;
- }
- // Build signatures for each annotated member and put them in a map from signature to
- // member.
- for (Element e : annotated) {
- String sig = sb.buildSignature(supportedAnnotation, e);
- if (sig != null) {
- signatureMap.put(sig, e);
- }
- }
- }
-
- if (!signatureMap.isEmpty()) {
- try {
- writeToFile(INDEX_CSV,
- getCsvHeaders(),
- signatureMap.entrySet()
- .stream()
- .map(e -> getAnnotationIndex(e.getKey(), e.getValue())));
- } catch (IOException e) {
- throw new RuntimeException("Failed to write output", e);
- }
- }
- return true;
- }
-}
diff --git a/tools/processors/unsupportedappusage/test/Android.bp b/tools/processors/unsupportedappusage/test/Android.bp
deleted file mode 100644
index e10fd47..0000000
--- a/tools/processors/unsupportedappusage/test/Android.bp
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_test_host {
- name: "unsupportedappusage-processor-test",
-
- srcs: ["src/**/*.java"],
-
- static_libs: [
- "compile-testing-prebuilt",
- "unsupportedappusage-annotation-processor-lib",
- "truth-host-prebuilt",
- "mockito-host",
- "junit-host",
- "objenesis",
- ],
-}
diff --git a/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/CsvReader.java b/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/CsvReader.java
deleted file mode 100644
index 23db99e..0000000
--- a/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/CsvReader.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.processor.unsupportedappusage;
-
-import com.google.common.base.Splitter;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class CsvReader {
-
- private final Splitter mSplitter;
- private final List<String> mColumns;
- private final List<Map<String, String>> mContents;
-
- public CsvReader(InputStream in) throws IOException {
- mSplitter = Splitter.on(",");
- BufferedReader br = new BufferedReader(new InputStreamReader(in));
- mColumns = mSplitter.splitToList(br.readLine());
- mContents = new ArrayList<>();
- String line = br.readLine();
- while (line != null) {
- List<String> contents = mSplitter.splitToList(line);
- Map<String, String> contentMap = new HashMap<>();
- for (int i = 0; i < Math.min(contents.size(), mColumns.size()); ++i) {
- contentMap.put(mColumns.get(i), contents.get(i));
- }
- mContents.add(contentMap);
- line = br.readLine();
- }
- br.close();
- }
-
- public List<String> getColumns() {
- return mColumns;
- }
-
- public List<Map<String, String>> getContents() {
- return mContents;
- }
-}
diff --git a/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessorTest.java b/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessorTest.java
deleted file mode 100644
index 75158ee..0000000
--- a/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessorTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.processor.unsupportedappusage;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.testing.compile.Compilation;
-import com.google.testing.compile.CompilationSubject;
-import com.google.testing.compile.Compiler;
-import com.google.testing.compile.JavaFileObjects;
-
-import org.junit.Test;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.Optional;
-
-import javax.tools.JavaFileObject;
-import javax.tools.StandardLocation;
-
-public class UnsupportedAppUsageProcessorTest {
-
- private static final JavaFileObject ANNOTATION = JavaFileObjects.forSourceLines(
- "dalvik.dalvik.annotation.compat.UnsupportedAppUsage",
- "package dalvik.annotation.compat;",
- "public @interface UnsupportedAppUsage {",
- " String expectedSignature() default \"\";\n",
- " String someProperty() default \"\";",
- " String overrideSourcePosition() default \"\";",
- "}");
-
- private CsvReader compileAndReadCsv(JavaFileObject source) throws IOException {
- Compilation compilation =
- Compiler.javac().withProcessors(new UnsupportedAppUsageProcessor())
- .compile(ANNOTATION, source);
- CompilationSubject.assertThat(compilation).succeeded();
- Optional<JavaFileObject> csv = compilation.generatedFile(StandardLocation.CLASS_OUTPUT,
- "unsupportedappusage/unsupportedappusage_index.csv");
- assertThat(csv.isPresent()).isTrue();
-
- return new CsvReader(csv.get().openInputStream());
- }
-
- @Test
- public void testSignatureFormat() throws Exception {
- JavaFileObject src = JavaFileObjects.forSourceLines("a.b.Class",
- "package a.b;",
- "import dalvik.annotation.compat.UnsupportedAppUsage;",
- "public class Class {",
- " @UnsupportedAppUsage",
- " public void method() {}",
- "}");
- assertThat(compileAndReadCsv(src).getContents().get(0)).containsEntry(
- "signature", "La/b/Class;->method()V"
- );
- }
-
- @Test
- public void testSourcePosition() throws Exception {
- JavaFileObject src = JavaFileObjects.forSourceLines("a.b.Class",
- "package a.b;", // 1
- "import dalvik.annotation.compat.UnsupportedAppUsage;", // 2
- "public class Class {", // 3
- " @UnsupportedAppUsage", // 4
- " public void method() {}", // 5
- "}");
- Map<String, String> row = compileAndReadCsv(src).getContents().get(0);
- assertThat(row).containsEntry("startline", "4");
- assertThat(row).containsEntry("startcol", "3");
- assertThat(row).containsEntry("endline", "4");
- assertThat(row).containsEntry("endcol", "23");
- }
-
- @Test
- public void testAnnotationProperties() throws Exception {
- JavaFileObject src = JavaFileObjects.forSourceLines("a.b.Class",
- "package a.b;", // 1
- "import dalvik.annotation.compat.UnsupportedAppUsage;", // 2
- "public class Class {", // 3
- " @UnsupportedAppUsage(someProperty=\"value\")", // 4
- " public void method() {}", // 5
- "}");
- assertThat(compileAndReadCsv(src).getContents().get(0)).containsEntry(
- "properties", "someProperty=%22value%22");
- }
-
- @Test
- public void testSourcePositionOverride() throws Exception {
- JavaFileObject src = JavaFileObjects.forSourceLines("a.b.Class",
- "package a.b;", // 1
- "import dalvik.annotation.compat.UnsupportedAppUsage;", // 2
- "public class Class {", // 3
- " @UnsupportedAppUsage(overrideSourcePosition=\"otherfile.aidl:30:10:31:20\")",
- " public void method() {}", // 5
- "}");
- Map<String, String> row = compileAndReadCsv(src).getContents().get(0);
- assertThat(row).containsEntry("file", "otherfile.aidl");
- assertThat(row).containsEntry("startline", "30");
- assertThat(row).containsEntry("startcol", "10");
- assertThat(row).containsEntry("endline", "31");
- assertThat(row).containsEntry("endcol", "20");
- assertThat(row).containsEntry("properties", "");
- }
-
- @Test
- public void testSourcePositionOverrideWrongFormat() throws Exception {
- JavaFileObject src = JavaFileObjects.forSourceLines("a.b.Class",
- "package a.b;", // 1
- "import dalvik.annotation.compat.UnsupportedAppUsage;", // 2
- "public class Class {", // 3
- " @UnsupportedAppUsage(overrideSourcePosition=\"invalid\")", // 4
- " public void method() {}", // 5
- "}");
- Compilation compilation =
- Compiler.javac().withProcessors(new UnsupportedAppUsageProcessor())
- .compile(ANNOTATION, src);
- CompilationSubject.assertThat(compilation).failed();
- CompilationSubject.assertThat(compilation).hadErrorContaining(
- "Expected overrideSourcePosition to have format "
- + "file:startLine:startCol:endLine:endCol").inFile(src).onLine(4);
- }
-
- @Test
- public void testSourcePositionOverrideInvalidInt() throws Exception {
- JavaFileObject src = JavaFileObjects.forSourceLines("a.b.Class",
- "package a.b;", // 1
- "import dalvik.annotation.compat.UnsupportedAppUsage;", // 2
- "public class Class {", // 3
- " @UnsupportedAppUsage(overrideSourcePosition=\"otherfile.aidl:a:b:c:d\")", // 4
- " public void method() {}", // 5
- "}");
- Compilation compilation =
- Compiler.javac().withProcessors(new UnsupportedAppUsageProcessor())
- .compile(ANNOTATION, src);
- CompilationSubject.assertThat(compilation).failed();
- CompilationSubject.assertThat(compilation).hadErrorContaining(
- "error parsing integer").inFile(src).onLine(4);
- }
-
-}
diff --git a/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl b/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl
new file mode 100644
index 0000000..7e25fd8
--- /dev/null
+++ b/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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 android.net.wifi;
+
+import android.os.connectivity.WifiActivityEnergyInfo;
+
+/**
+ * Interface for Wi-Fi activity energy info listener.
+ *
+ * @hide
+ */
+oneway interface IOnWifiActivityEnergyInfoListener
+{
+ /**
+ * Service to manager callback providing current Wi-Fi activity energy info.
+ * @param info the Wi-Fi activity energy info
+ */
+ void onWifiActivityEnergyInfo(in WifiActivityEnergyInfo info);
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 032f66a..fccbcf7 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -28,15 +28,15 @@
import android.net.wifi.IDppCallback;
import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.INetworkRequestMatchCallback;
+import android.net.wifi.IOnWifiActivityEnergyInfoListener;
+import android.net.wifi.IOnWifiUsabilityStatsListener;
import android.net.wifi.IScanResultsCallback;
import android.net.wifi.ISoftApCallback;
import android.net.wifi.ISuggestionConnectionStatusListener;
import android.net.wifi.ITrafficStateCallback;
import android.net.wifi.ITxPacketCountListener;
-import android.net.wifi.IOnWifiUsabilityStatsListener;
import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
-import android.net.wifi.WifiActivityEnergyInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiNetworkSuggestion;
@@ -44,6 +44,7 @@
import android.os.Messenger;
import android.os.ResultReceiver;
import android.os.WorkSource;
+import android.os.connectivity.WifiActivityEnergyInfo;
/**
* Interface that allows controlling and querying Wi-Fi connectivity.
@@ -56,13 +57,7 @@
WifiActivityEnergyInfo reportActivityInfo();
- /**
- * Requests the controller activity info asynchronously.
- * The implementor is expected to reply with the
- * {@link android.net.wifi.WifiActivityEnergyInfo} object placed into the Bundle with the key
- * {@link android.os.BatteryStats#RESULT_RECEIVER_CONTROLLER_KEY}. The result code is ignored.
- */
- oneway void requestActivityInfo(in ResultReceiver result);
+ oneway void getWifiActivityEnergyInfoAsync(in IOnWifiActivityEnergyInfoListener listener);
ParceledListSlice getConfiguredNetworks(String packageName, String featureId);
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 9956901..729ef61 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -499,6 +499,13 @@
/**
* @hide
+ */
+ public boolean is6GHz() {
+ return ScanResult.is6GHz(frequency);
+ }
+
+ /**
+ * @hide
* TODO: makes real freq boundaries
*/
public static boolean is5GHz(int freq) {
@@ -506,6 +513,13 @@
}
/**
+ * @hide
+ */
+ public static boolean is6GHz(int freq) {
+ return freq > 5925 && freq < 7125;
+ }
+
+ /**
* @hide
* anqp lines from supplicant BSS response
*/
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 15d897d..0108d5a 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -49,6 +49,7 @@
import android.os.Looper;
import android.os.RemoteException;
import android.os.WorkSource;
+import android.os.connectivity.WifiActivityEnergyInfo;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -1246,6 +1247,7 @@
* <li>allowedAuthAlgorithms</li>
* <li>allowedPairwiseCiphers</li>
* <li>allowedGroupCiphers</li>
+ * <li>status</li>
* </ul>
* @return a list of network configurations in the form of a list
* of {@link WifiConfiguration} objects.
@@ -2396,6 +2398,82 @@
}
/**
+ * Interface for Wi-Fi activity energy info listener. Should be implemented by applications and
+ * set when calling {@link WifiManager#getWifiActivityEnergyInfoAsync}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface OnWifiActivityEnergyInfoListener {
+ /**
+ * Called when Wi-Fi activity energy info is available.
+ * Note: this listener is triggered at most once for each call to
+ * {@link #getWifiActivityEnergyInfoAsync}.
+ *
+ * @param info the latest {@link WifiActivityEnergyInfo}, or null if unavailable.
+ */
+ void onWifiActivityEnergyInfo(@Nullable WifiActivityEnergyInfo info);
+ }
+
+ private static class OnWifiActivityEnergyInfoProxy
+ extends IOnWifiActivityEnergyInfoListener.Stub {
+ private final Object mLock = new Object();
+ @Nullable @GuardedBy("mLock") private Executor mExecutor;
+ @Nullable @GuardedBy("mLock") private OnWifiActivityEnergyInfoListener mListener;
+
+ OnWifiActivityEnergyInfoProxy(Executor executor,
+ OnWifiActivityEnergyInfoListener listener) {
+ mExecutor = executor;
+ mListener = listener;
+ }
+
+ @Override
+ public void onWifiActivityEnergyInfo(WifiActivityEnergyInfo info) {
+ Executor executor;
+ OnWifiActivityEnergyInfoListener listener;
+ synchronized (mLock) {
+ if (mExecutor == null || mListener == null) {
+ return;
+ }
+ executor = mExecutor;
+ listener = mListener;
+ // null out to allow garbage collection, prevent triggering listener more than once
+ mExecutor = null;
+ mListener = null;
+ }
+ Binder.clearCallingIdentity();
+ executor.execute(() -> listener.onWifiActivityEnergyInfo(info));
+ }
+ }
+
+ /**
+ * Request to get the current {@link WifiActivityEnergyInfo} asynchronously.
+ * Note: This method will return null if {@link #isEnhancedPowerReportingSupported()} returns
+ * false.
+ *
+ * @param executor the executor that the listener will be invoked on
+ * @param listener the listener that will receive the {@link WifiActivityEnergyInfo} object
+ * when it becomes available. The listener will be triggered at most once for
+ * each call to this method.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(ACCESS_WIFI_STATE)
+ public void getWifiActivityEnergyInfoAsync(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnWifiActivityEnergyInfoListener listener) {
+ if (executor == null) throw new IllegalArgumentException("executor cannot be null");
+ if (listener == null) throw new IllegalArgumentException("listener cannot be null");
+ try {
+ mService.getWifiActivityEnergyInfoAsync(
+ new OnWifiActivityEnergyInfoProxy(executor, listener));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Request a scan for access points. Returns immediately. The availability
* of the results is made known later by means of an asynchronous event sent
* on completion of the scan.
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index c743b63..760497b 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -740,6 +740,8 @@
public int min5GHzRssi;
/** Minimum 2.4GHz RSSI for a BSSID to be considered */
public int min24GHzRssi;
+ /** Minimum 6GHz RSSI for a BSSID to be considered */
+ public int min6GHzRssi;
/** Maximum score that a network can have before bonuses */
public int initialScoreMax;
/**
@@ -753,6 +755,8 @@
public int secureBonus;
/** 5GHz RSSI score bonus (applied to all 5GHz networks) */
public int band5GHzBonus;
+ /** 6GHz RSSI score bonus (applied to all 5GHz networks) */
+ public int band6GHzBonus;
/** Pno Network filter list */
public PnoNetwork[] networkList;
@@ -766,11 +770,13 @@
dest.writeInt(isConnected ? 1 : 0);
dest.writeInt(min5GHzRssi);
dest.writeInt(min24GHzRssi);
+ dest.writeInt(min6GHzRssi);
dest.writeInt(initialScoreMax);
dest.writeInt(currentConnectionBonus);
dest.writeInt(sameNetworkBonus);
dest.writeInt(secureBonus);
dest.writeInt(band5GHzBonus);
+ dest.writeInt(band6GHzBonus);
if (networkList != null) {
dest.writeInt(networkList.length);
for (int i = 0; i < networkList.length; i++) {
@@ -792,11 +798,13 @@
settings.isConnected = in.readInt() == 1;
settings.min5GHzRssi = in.readInt();
settings.min24GHzRssi = in.readInt();
+ settings.min6GHzRssi = in.readInt();
settings.initialScoreMax = in.readInt();
settings.currentConnectionBonus = in.readInt();
settings.sameNetworkBonus = in.readInt();
settings.secureBonus = in.readInt();
settings.band5GHzBonus = in.readInt();
+ settings.band6GHzBonus = in.readInt();
int numNetworks = in.readInt();
settings.networkList = new PnoNetwork[numNetworks];
for (int i = 0; i < numNetworks; i++) {
diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java
index bc86839..367cfa0 100644
--- a/wifi/java/com/android/server/wifi/BaseWifiService.java
+++ b/wifi/java/com/android/server/wifi/BaseWifiService.java
@@ -25,6 +25,7 @@
import android.net.wifi.IDppCallback;
import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.INetworkRequestMatchCallback;
+import android.net.wifi.IOnWifiActivityEnergyInfoListener;
import android.net.wifi.IOnWifiUsabilityStatsListener;
import android.net.wifi.IScanResultsCallback;
import android.net.wifi.IScanResultsListener;
@@ -35,7 +36,6 @@
import android.net.wifi.IWifiManager;
import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
-import android.net.wifi.WifiActivityEnergyInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiNetworkSuggestion;
@@ -46,6 +46,7 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.WorkSource;
+import android.os.connectivity.WifiActivityEnergyInfo;
import java.util.List;
import java.util.Map;
@@ -80,12 +81,16 @@
throw new UnsupportedOperationException();
}
- @Override
public void requestActivityInfo(ResultReceiver result) {
throw new UnsupportedOperationException();
}
@Override
+ public void getWifiActivityEnergyInfoAsync(IOnWifiActivityEnergyInfoListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public ParceledListSlice getConfiguredNetworks(String packageName, String featureId) {
throw new UnsupportedOperationException();
}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index b3a73bc..de45149 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -16,15 +16,31 @@
package android.net.wifi;
+import static android.net.wifi.WifiManager.ActionListener;
+import static android.net.wifi.WifiManager.BUSY;
+import static android.net.wifi.WifiManager.ERROR;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.REQUEST_REGISTERED;
+import static android.net.wifi.WifiManager.NOT_AUTHORIZED;
+import static android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener;
import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
+import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
+import static android.net.wifi.WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
+import static android.net.wifi.WifiManager.TxPacketCountListener;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_P2P;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_SCANNER;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
+import static android.net.wifi.WifiManager.WpsCallback;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -71,6 +87,7 @@
import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.connectivity.WifiActivityEnergyInfo;
import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
@@ -113,6 +130,7 @@
@Mock TrafficStateCallback mTrafficStateCallback;
@Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback;
@Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
+ @Mock OnWifiActivityEnergyInfoListener mOnWifiActivityEnergyInfoListener;
@Mock SuggestionConnectionStatusListener mListener;
@Mock Runnable mRunnable;
@Mock Executor mExecutor;
@@ -124,6 +142,7 @@
private WifiManager mWifiManager;
private WifiNetworkSuggestion mWifiNetworkSuggestion;
private ScanResultsCallback mScanResultsCallback;
+ private WifiActivityEnergyInfo mWifiActivityEnergyInfo;
@Before
public void setUp() throws Exception {
@@ -142,6 +161,7 @@
mRunnable.run();
}
};
+ mWifiActivityEnergyInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0, 0);
}
/**
@@ -1069,7 +1089,7 @@
}
- class WpsCallbackTester extends WifiManager.WpsCallback {
+ class WpsCallbackTester extends WpsCallback {
public boolean mStarted = false;
public boolean mSucceeded = false;
public boolean mFailed = false;
@@ -1101,7 +1121,7 @@
WpsCallbackTester wpsCallback = new WpsCallbackTester();
mWifiManager.startWps(null, wpsCallback);
assertTrue(wpsCallback.mFailed);
- assertEquals(WifiManager.ERROR, wpsCallback.mFailureCode);
+ assertEquals(ERROR, wpsCallback.mFailureCode);
assertFalse(wpsCallback.mStarted);
assertFalse(wpsCallback.mSucceeded);
verifyNoMoreInteractions(mWifiService);
@@ -1124,7 +1144,7 @@
WpsCallbackTester wpsCallback = new WpsCallbackTester();
mWifiManager.cancelWps(wpsCallback);
assertTrue(wpsCallback.mFailed);
- assertEquals(WifiManager.ERROR, wpsCallback.mFailureCode);
+ assertEquals(ERROR, wpsCallback.mFailureCode);
assertFalse(wpsCallback.mStarted);
assertFalse(wpsCallback.mSucceeded);
verifyNoMoreInteractions(mWifiService);
@@ -1437,13 +1457,13 @@
public void addGetRemoveNetworkSuggestions() throws Exception {
List<WifiNetworkSuggestion> testList = new ArrayList<>();
when(mWifiService.addNetworkSuggestions(any(List.class), anyString(),
- nullable(String.class))).thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
+ nullable(String.class))).thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS);
when(mWifiService.removeNetworkSuggestions(any(List.class), anyString())).thenReturn(
- WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
+ STATUS_NETWORK_SUGGESTIONS_SUCCESS);
when(mWifiService.getNetworkSuggestions(anyString()))
.thenReturn(testList);
- assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
+ assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiManager.addNetworkSuggestions(testList));
verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME),
nullable(String.class));
@@ -1451,7 +1471,7 @@
assertEquals(testList, mWifiManager.getNetworkSuggestions());
verify(mWifiService).getNetworkSuggestions(eq(TEST_PACKAGE_NAME));
- assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
+ assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiManager.removeNetworkSuggestions(new ArrayList<>()));
verify(mWifiService).removeNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME));
}
@@ -1515,10 +1535,10 @@
@Test
public void testIsEnhancedOpenSupported() throws Exception {
when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(WifiManager.WIFI_FEATURE_OWE));
+ .thenReturn(new Long(WIFI_FEATURE_OWE));
assertTrue(mWifiManager.isEnhancedOpenSupported());
when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(~WifiManager.WIFI_FEATURE_OWE));
+ .thenReturn(new Long(~WIFI_FEATURE_OWE));
assertFalse(mWifiManager.isEnhancedOpenSupported());
}
@@ -1528,10 +1548,10 @@
@Test
public void testIsWpa3SaeSupported() throws Exception {
when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SAE));
+ .thenReturn(new Long(WIFI_FEATURE_WPA3_SAE));
assertTrue(mWifiManager.isWpa3SaeSupported());
when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SAE));
+ .thenReturn(new Long(~WIFI_FEATURE_WPA3_SAE));
assertFalse(mWifiManager.isWpa3SaeSupported());
}
@@ -1541,10 +1561,10 @@
@Test
public void testIsWpa3SuiteBSupported() throws Exception {
when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SUITE_B));
+ .thenReturn(new Long(WIFI_FEATURE_WPA3_SUITE_B));
assertTrue(mWifiManager.isWpa3SuiteBSupported());
when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SUITE_B));
+ .thenReturn(new Long(~WIFI_FEATURE_WPA3_SUITE_B));
assertFalse(mWifiManager.isWpa3SuiteBSupported());
}
@@ -1554,10 +1574,10 @@
@Test
public void testIsEasyConnectSupported() throws Exception {
when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(WifiManager.WIFI_FEATURE_DPP));
+ .thenReturn(new Long(WIFI_FEATURE_DPP));
assertTrue(mWifiManager.isEasyConnectSupported());
when(mWifiService.getSupportedFeatures())
- .thenReturn(new Long(~WifiManager.WIFI_FEATURE_DPP));
+ .thenReturn(new Long(~WIFI_FEATURE_DPP));
assertFalse(mWifiManager.isEasyConnectSupported());
}
@@ -1666,9 +1686,9 @@
@Test
public void testGetSupportedFeatures() throws Exception {
long supportedFeatures =
- WifiManager.WIFI_FEATURE_SCANNER
- | WifiManager.WIFI_FEATURE_PASSPOINT
- | WifiManager.WIFI_FEATURE_P2P;
+ WIFI_FEATURE_SCANNER
+ | WIFI_FEATURE_PASSPOINT
+ | WIFI_FEATURE_P2P;
when(mWifiService.getSupportedFeatures())
.thenReturn(Long.valueOf(supportedFeatures));
@@ -1700,6 +1720,58 @@
}
/**
+ * Tests that passing a null Executor to {@link WifiManager#getWifiActivityEnergyInfoAsync}
+ * throws an exception.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testGetWifiActivityInfoNullExecutor() throws Exception {
+ mWifiManager.getWifiActivityEnergyInfoAsync(null, mOnWifiActivityEnergyInfoListener);
+ }
+
+ /**
+ * Tests that passing a null listener to {@link WifiManager#getWifiActivityEnergyInfoAsync}
+ * throws an exception.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testGetWifiActivityInfoNullListener() throws Exception {
+ mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, null);
+ }
+
+ /** Tests that the listener runs on the correct Executor. */
+ @Test
+ public void testGetWifiActivityInfoRunsOnCorrectExecutor() throws Exception {
+ mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, mOnWifiActivityEnergyInfoListener);
+ ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor =
+ ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class);
+ verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture());
+ IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue();
+ listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
+ verify(mExecutor).execute(any());
+
+ // ensure that the executor is only triggered once
+ listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
+ verify(mExecutor).execute(any());
+ }
+
+ /** Tests that the correct listener runs. */
+ @Test
+ public void testGetWifiActivityInfoRunsCorrectListener() throws Exception {
+ int[] flag = {0};
+ mWifiManager.getWifiActivityEnergyInfoAsync(
+ new SynchronousExecutor(), info -> flag[0]++);
+ ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor =
+ ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class);
+ verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture());
+ IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue();
+ listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
+ assertEquals(1, flag[0]);
+
+ // ensure that the listener is only triggered once
+ listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo);
+ assertEquals(1, flag[0]);
+ }
+
+ /**
* Test behavior of {@link WifiManager#getConnectionInfo()}
*/
@Test
@@ -1756,11 +1828,11 @@
}
/**
- * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)}
+ * Test behavior of {@link WifiManager#connect(int, ActionListener)}
*/
@Test
public void testConnectWithListener() throws Exception {
- WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class);
+ ActionListener externalListener = mock(ActionListener.class);
mWifiManager.connect(TEST_NETWORK_ID, externalListener);
ArgumentCaptor<IActionListener> binderListenerCaptor =
@@ -1775,43 +1847,43 @@
verify(externalListener).onSuccess();
// Trigger on failure.
- binderListenerCaptor.getValue().onFailure(WifiManager.BUSY);
+ binderListenerCaptor.getValue().onFailure(BUSY);
mLooper.dispatchAll();
- verify(externalListener).onFailure(WifiManager.BUSY);
+ verify(externalListener).onFailure(BUSY);
}
/**
- * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)}
+ * Test behavior of {@link WifiManager#connect(int, ActionListener)}
*/
@Test
public void testConnectWithListenerHandleSecurityException() throws Exception {
doThrow(new SecurityException()).when(mWifiService)
.connect(eq(null), anyInt(), any(IBinder.class),
any(IActionListener.class), anyInt());
- WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class);
+ ActionListener externalListener = mock(ActionListener.class);
mWifiManager.connect(TEST_NETWORK_ID, externalListener);
mLooper.dispatchAll();
- verify(externalListener).onFailure(WifiManager.NOT_AUTHORIZED);
+ verify(externalListener).onFailure(NOT_AUTHORIZED);
}
/**
- * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)}
+ * Test behavior of {@link WifiManager#connect(int, ActionListener)}
*/
@Test
public void testConnectWithListenerHandleRemoteException() throws Exception {
doThrow(new RemoteException()).when(mWifiService)
.connect(eq(null), anyInt(), any(IBinder.class),
any(IActionListener.class), anyInt());
- WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class);
+ ActionListener externalListener = mock(ActionListener.class);
mWifiManager.connect(TEST_NETWORK_ID, externalListener);
mLooper.dispatchAll();
- verify(externalListener).onFailure(WifiManager.ERROR);
+ verify(externalListener).onFailure(ERROR);
}
/**
- * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)}
+ * Test behavior of {@link WifiManager#connect(int, ActionListener)}
*/
@Test
public void testConnectWithoutListener() throws Exception {
@@ -1823,12 +1895,12 @@
}
/**
- * Test behavior of {@link WifiManager#getTxPacketCount(WifiManager.TxPacketCountListener)}
+ * Test behavior of {@link WifiManager#getTxPacketCount(TxPacketCountListener)}
*/
@Test
public void testGetTxPacketCount() throws Exception {
- WifiManager.TxPacketCountListener externalListener =
- mock(WifiManager.TxPacketCountListener.class);
+ TxPacketCountListener externalListener =
+ mock(TxPacketCountListener.class);
mWifiManager.getTxPacketCount(externalListener);
ArgumentCaptor<ITxPacketCountListener> binderListenerCaptor =
@@ -1843,9 +1915,9 @@
verify(externalListener).onSuccess(6);
// Trigger on failure.
- binderListenerCaptor.getValue().onFailure(WifiManager.BUSY);
+ binderListenerCaptor.getValue().onFailure(BUSY);
mLooper.dispatchAll();
- verify(externalListener).onFailure(WifiManager.BUSY);
+ verify(externalListener).onFailure(BUSY);
}
/**
@@ -1947,7 +2019,7 @@
*/
@Test
public void testAddSuggestionConnectionStatusListenerAndReceiveEvent() throws Exception {
- int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
+ int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
Executor executor = new SynchronousExecutor();
@@ -1963,7 +2035,7 @@
*/
@Test
public void testAddSuggestionConnectionStatusListenerWithTheTargetExecutor() throws Exception {
- int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
+ int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor =
ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class);
mWifiManager.addSuggestionConnectionStatusListener(mExecutor, mListener);
diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java
index b1436c90..fa4f711 100644
--- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java
@@ -79,15 +79,17 @@
private static final boolean TEST_PNOSETTINGS_IS_CONNECTED = false;
private static final int TEST_PNOSETTINGS_MIN_5GHZ_RSSI = -60;
private static final int TEST_PNOSETTINGS_MIN_2GHZ_RSSI = -70;
+ private static final int TEST_PNOSETTINGS_MIN_6GHZ_RSSI = -55;
private static final int TEST_PNOSETTINGS_INITIAL_SCORE_MAX = 50;
private static final int TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS = 10;
private static final int TEST_PNOSETTINGS_SAME_NETWORK_BONUS = 11;
private static final int TEST_PNOSETTINGS_SECURE_BONUS = 12;
private static final int TEST_PNOSETTINGS_BAND_5GHZ_BONUS = 13;
+ private static final int TEST_PNOSETTINGS_BAND_6GHZ_BONUS = 15;
private static final String TEST_SSID_1 = "TEST1";
private static final String TEST_SSID_2 = "TEST2";
private static final int[] TEST_FREQUENCIES_1 = {};
- private static final int[] TEST_FREQUENCIES_2 = {2500, 5124};
+ private static final int[] TEST_FREQUENCIES_2 = {2500, 5124, 6245};
private static final String DESCRIPTION_NOT_AUTHORIZED = "Not authorized";
private WifiScanner mWifiScanner;
@@ -183,11 +185,13 @@
pnoSettings.isConnected = TEST_PNOSETTINGS_IS_CONNECTED;
pnoSettings.min5GHzRssi = TEST_PNOSETTINGS_MIN_5GHZ_RSSI;
pnoSettings.min24GHzRssi = TEST_PNOSETTINGS_MIN_2GHZ_RSSI;
+ pnoSettings.min6GHzRssi = TEST_PNOSETTINGS_MIN_6GHZ_RSSI;
pnoSettings.initialScoreMax = TEST_PNOSETTINGS_INITIAL_SCORE_MAX;
pnoSettings.currentConnectionBonus = TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS;
pnoSettings.sameNetworkBonus = TEST_PNOSETTINGS_SAME_NETWORK_BONUS;
pnoSettings.secureBonus = TEST_PNOSETTINGS_SECURE_BONUS;
pnoSettings.band5GHzBonus = TEST_PNOSETTINGS_BAND_5GHZ_BONUS;
+ pnoSettings.band6GHzBonus = TEST_PNOSETTINGS_BAND_6GHZ_BONUS;
Parcel parcel = Parcel.obtain();
pnoSettings.writeToParcel(parcel, 0);
@@ -200,6 +204,7 @@
assertEquals(TEST_PNOSETTINGS_IS_CONNECTED, pnoSettingsDeserialized.isConnected);
assertEquals(TEST_PNOSETTINGS_MIN_5GHZ_RSSI, pnoSettingsDeserialized.min5GHzRssi);
assertEquals(TEST_PNOSETTINGS_MIN_2GHZ_RSSI, pnoSettingsDeserialized.min24GHzRssi);
+ assertEquals(TEST_PNOSETTINGS_MIN_6GHZ_RSSI, pnoSettingsDeserialized.min6GHzRssi);
assertEquals(TEST_PNOSETTINGS_INITIAL_SCORE_MAX, pnoSettingsDeserialized.initialScoreMax);
assertEquals(TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS,
pnoSettingsDeserialized.currentConnectionBonus);
@@ -207,6 +212,7 @@
pnoSettingsDeserialized.sameNetworkBonus);
assertEquals(TEST_PNOSETTINGS_SECURE_BONUS, pnoSettingsDeserialized.secureBonus);
assertEquals(TEST_PNOSETTINGS_BAND_5GHZ_BONUS, pnoSettingsDeserialized.band5GHzBonus);
+ assertEquals(TEST_PNOSETTINGS_BAND_6GHZ_BONUS, pnoSettingsDeserialized.band6GHzBonus);
// Test parsing of PnoNetwork
assertEquals(pnoSettings.networkList.length, pnoSettingsDeserialized.networkList.length);