Merge "Add OWNERS for text related classes"
diff --git a/Android.bp b/Android.bp
index 979ed1c..e23d9c2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -215,7 +215,6 @@
"core/java/android/os/IDeviceIdleController.aidl",
"core/java/android/os/IHardwarePropertiesManager.aidl",
"core/java/android/os/IIncidentManager.aidl",
- "core/java/android/os/IIncidentReportCompletedListener.aidl",
"core/java/android/os/IIncidentReportStatusListener.aidl",
"core/java/android/os/IMaintenanceActivityListener.aidl",
"core/java/android/os/IMessenger.aidl",
@@ -671,6 +670,7 @@
"libphonenumber-platform",
"nist-sip",
"tagsoup",
+ "rappor",
],
dxflags: ["--core-library"],
}
@@ -693,7 +693,6 @@
srcs: [
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
- "tools/streaming_proto/stream.proto",
],
target: {
diff --git a/Android.mk b/Android.mk
index 1035362..995630b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -274,6 +274,9 @@
../opt/net/voip/src/java/android/net/rtp \
../opt/net/voip/src/java/android/net/sip \
+framework_base_android_test_base_src_files := \
+ $(call all-java-files-under, test-base/src/junit)
+
framework_base_android_test_mock_src_files := \
$(call all-java-files-under, test-mock/src/android/test/mock)
@@ -284,7 +287,6 @@
# to document and check apis
files_to_check_apis := \
$(call find-other-java-files, \
- test-base/src \
$(non_base_dirs) \
)
@@ -308,6 +310,7 @@
files_to_document := \
$(files_to_check_apis) \
$(call find-other-java-files,\
+ test-base/src \
test-runner/src)
# These are relative to frameworks/base
@@ -327,6 +330,7 @@
# These are relative to frameworks/base
framework_docs_LOCAL_API_CHECK_SRC_FILES := \
+ $(framework_base_android_test_base_src_files) \
$(framework_base_android_test_mock_src_files) \
$(framework_base_android_test_runner_src_files) \
$(files_to_check_apis) \
@@ -999,7 +1003,6 @@
-Iexternal/protobuf/src
LOCAL_SOURCE_FILES_ALL_GENERATED := true
LOCAL_SRC_FILES := \
- tools/streaming_proto/stream.proto \
cmds/am/proto/instrumentation_data.proto \
$(call all-proto-files-under, core/proto) \
$(call all-proto-files-under, libs/incident/proto) \
diff --git a/api/current.txt b/api/current.txt
index 9bdcdad..8a20da2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3953,7 +3953,7 @@
field public static final android.os.Parcelable.Creator<android.app.ActivityManager.RunningAppProcessInfo> CREATOR;
field public static final deprecated int IMPORTANCE_BACKGROUND = 400; // 0x190
field public static final int IMPORTANCE_CACHED = 400; // 0x190
- field public static final int IMPORTANCE_CANT_SAVE_STATE = 270; // 0x10e
+ field public static final int IMPORTANCE_CANT_SAVE_STATE = 350; // 0x15e
field public static final deprecated int IMPORTANCE_EMPTY = 500; // 0x1f4
field public static final int IMPORTANCE_FOREGROUND = 100; // 0x64
field public static final int IMPORTANCE_FOREGROUND_SERVICE = 125; // 0x7d
@@ -3961,7 +3961,8 @@
field public static final int IMPORTANCE_PERCEPTIBLE = 230; // 0xe6
field public static final int IMPORTANCE_PERCEPTIBLE_PRE_26 = 130; // 0x82
field public static final int IMPORTANCE_SERVICE = 300; // 0x12c
- field public static final int IMPORTANCE_TOP_SLEEPING = 150; // 0x96
+ field public static final int IMPORTANCE_TOP_SLEEPING = 325; // 0x145
+ field public static final deprecated int IMPORTANCE_TOP_SLEEPING_PRE_28 = 150; // 0x96
field public static final int IMPORTANCE_VISIBLE = 200; // 0xc8
field public static final int REASON_PROVIDER_IN_USE = 1; // 0x1
field public static final int REASON_SERVICE_IN_USE = 2; // 0x2
@@ -37692,11 +37693,8 @@
field public static final android.os.Parcelable.Creator<android.service.autofill.EditDistanceScorer> CREATOR;
}
- public final class FieldClassification implements android.os.Parcelable {
- method public int describeContents();
+ public final class FieldClassification {
method public java.util.List<android.service.autofill.FieldClassification.Match> getMatches();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.service.autofill.FieldClassification> CREATOR;
}
public static final class FieldClassification.Match {
@@ -40344,6 +40342,7 @@
public class CarrierConfigManager {
method public android.os.PersistableBundle getConfig();
method public android.os.PersistableBundle getConfigForSubId(int);
+ method public static boolean isConfigForIdentifiedCarrier(android.os.PersistableBundle);
method public void notifyConfigChangedForSubId(int);
field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
field public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
@@ -41099,11 +41098,12 @@
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
method public boolean isConcurrentVoiceAndDataSupported();
- method public boolean isDataEnabled();
+ method public deprecated boolean isDataEnabled();
method public boolean isHearingAidCompatibilitySupported();
method public boolean isNetworkRoaming();
method public boolean isSmsCapable();
method public deprecated boolean isTtyModeSupported();
+ method public boolean isUserMobileDataEnabled();
method public boolean isVoiceCapable();
method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
method public boolean isWorldPhone();
@@ -41112,10 +41112,11 @@
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
method public void sendVisualVoicemailSms(java.lang.String, int, java.lang.String, android.app.PendingIntent);
- method public void setDataEnabled(boolean);
+ method public deprecated void setDataEnabled(boolean);
method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
method public boolean setOperatorBrandOverride(java.lang.String);
method public boolean setPreferredNetworkTypeToGlobal();
+ method public void setUserMobileDataEnabled(boolean);
method public void setVisualVoicemailSmsFilterSettings(android.telephony.VisualVoicemailSmsFilterSettings);
method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
method public deprecated void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
@@ -41511,61 +41512,6 @@
}
-package android.test {
-
- public deprecated class AndroidTestCase extends junit.framework.TestCase {
- ctor public AndroidTestCase();
- method public void assertActivityRequiresPermission(java.lang.String, java.lang.String, java.lang.String);
- method public void assertReadingContentUriRequiresPermission(android.net.Uri, java.lang.String);
- method public void assertWritingContentUriRequiresPermission(android.net.Uri, java.lang.String);
- method public android.content.Context getContext();
- method protected void scrubClass(java.lang.Class<?>) throws java.lang.IllegalAccessException;
- method public void setContext(android.content.Context);
- method public void testAndroidTestCaseSetupProperly();
- field protected android.content.Context mContext;
- }
-
- public abstract deprecated class FlakyTest implements java.lang.annotation.Annotation {
- }
-
- public deprecated class InstrumentationTestCase extends junit.framework.TestCase {
- ctor public InstrumentationTestCase();
- method public android.app.Instrumentation getInstrumentation();
- method public deprecated void injectInsrumentation(android.app.Instrumentation);
- method public void injectInstrumentation(android.app.Instrumentation);
- method public final <T extends android.app.Activity> T launchActivity(java.lang.String, java.lang.Class<T>, android.os.Bundle);
- method public final <T extends android.app.Activity> T launchActivityWithIntent(java.lang.String, java.lang.Class<T>, android.content.Intent);
- method public void runTestOnUiThread(java.lang.Runnable) throws java.lang.Throwable;
- method public void sendKeys(java.lang.String);
- method public void sendKeys(int...);
- method public void sendRepeatedKeys(int...);
- }
-
- public deprecated class InstrumentationTestSuite extends junit.framework.TestSuite {
- ctor public InstrumentationTestSuite(android.app.Instrumentation);
- ctor public InstrumentationTestSuite(java.lang.String, android.app.Instrumentation);
- ctor public InstrumentationTestSuite(java.lang.Class, android.app.Instrumentation);
- method public void addTestSuite(java.lang.Class);
- }
-
- public abstract deprecated interface PerformanceTestCase {
- method public abstract boolean isPerformanceOnly();
- method public abstract int startPerformance(android.test.PerformanceTestCase.Intermediates);
- }
-
- public static abstract interface PerformanceTestCase.Intermediates {
- method public abstract void addIntermediate(java.lang.String);
- method public abstract void addIntermediate(java.lang.String, long);
- method public abstract void finishTiming(boolean);
- method public abstract void setInternalIterations(int);
- method public abstract void startTiming(boolean);
- }
-
- public abstract deprecated class UiThreadTest implements java.lang.annotation.Annotation {
- }
-
-}
-
package android.test.mock {
public deprecated class MockApplication extends android.app.Application {
@@ -41859,25 +41805,6 @@
}
-package android.test.suitebuilder.annotation {
-
- public abstract deprecated class LargeTest implements java.lang.annotation.Annotation {
- }
-
- public abstract deprecated class MediumTest implements java.lang.annotation.Annotation {
- }
-
- public abstract deprecated class SmallTest implements java.lang.annotation.Annotation {
- }
-
- public abstract deprecated class Smoke implements java.lang.annotation.Annotation {
- }
-
- public abstract deprecated class Suppress implements java.lang.annotation.Annotation {
- }
-
-}
-
package android.text {
public class AlteredCharSequence implements java.lang.CharSequence android.text.GetChars {
@@ -49193,9 +49120,13 @@
method public default android.view.textclassifier.TextClassification classifyText(java.lang.CharSequence, int, int, android.os.LocaleList);
method public default android.view.textclassifier.TextLinks generateLinks(java.lang.CharSequence, android.view.textclassifier.TextLinks.Options);
method public default android.view.textclassifier.TextLinks generateLinks(java.lang.CharSequence);
+ method public default java.util.Collection<java.lang.String> getEntitiesForPreset(int);
method public default android.view.textclassifier.TextSelection suggestSelection(java.lang.CharSequence, int, int, android.view.textclassifier.TextSelection.Options);
method public default android.view.textclassifier.TextSelection suggestSelection(java.lang.CharSequence, int, int);
method public default android.view.textclassifier.TextSelection suggestSelection(java.lang.CharSequence, int, int, android.os.LocaleList);
+ field public static final int ENTITY_PRESET_ALL = 0; // 0x0
+ field public static final int ENTITY_PRESET_BASE = 2; // 0x2
+ field public static final int ENTITY_PRESET_NONE = 1; // 0x1
field public static final android.view.textclassifier.TextClassifier NO_OP;
field public static final java.lang.String TYPE_ADDRESS = "address";
field public static final java.lang.String TYPE_EMAIL = "email";
@@ -49205,6 +49136,13 @@
field public static final java.lang.String TYPE_URL = "url";
}
+ public static final class TextClassifier.EntityConfig {
+ ctor public TextClassifier.EntityConfig(int);
+ method public android.view.textclassifier.TextClassifier.EntityConfig excludeEntities(java.lang.String...);
+ method public java.util.List<java.lang.String> getEntities(android.view.textclassifier.TextClassifier);
+ method public android.view.textclassifier.TextClassifier.EntityConfig includeEntities(java.lang.String...);
+ }
+
public final class TextLinks {
method public boolean apply(android.text.SpannableString, java.util.function.Function<android.view.textclassifier.TextLinks.TextLink, android.text.style.ClickableSpan>);
method public java.util.Collection<android.view.textclassifier.TextLinks.TextLink> getLinks();
@@ -49219,7 +49157,9 @@
public static final class TextLinks.Options {
ctor public TextLinks.Options();
method public android.os.LocaleList getDefaultLocales();
+ method public android.view.textclassifier.TextClassifier.EntityConfig getEntityConfig();
method public android.view.textclassifier.TextLinks.Options setDefaultLocales(android.os.LocaleList);
+ method public android.view.textclassifier.TextLinks.Options setEntityConfig(android.view.textclassifier.TextClassifier.EntityConfig);
}
public static final class TextLinks.TextLink {
@@ -49920,6 +49860,7 @@
method public android.print.PrintDocumentAdapter createPrintDocumentAdapter(java.lang.String);
method public android.webkit.WebMessagePort[] createWebMessageChannel();
method public void destroy();
+ method public static void disableWebView();
method public void documentHasImages(android.os.Message);
method public static void enableSlowWholeDocumentDraw();
method public void evaluateJavascript(java.lang.String, android.webkit.ValueCallback<java.lang.String>);
@@ -49980,6 +49921,7 @@
method public void saveWebArchive(java.lang.String);
method public void saveWebArchive(java.lang.String, boolean, android.webkit.ValueCallback<java.lang.String>);
method public deprecated void setCertificate(android.net.http.SslCertificate);
+ method public static void setDataDirectorySuffix(java.lang.String);
method public void setDownloadListener(android.webkit.DownloadListener);
method public void setFindListener(android.webkit.WebView.FindListener);
method public deprecated void setHorizontalScrollbarOverlay(boolean);
diff --git a/api/system-current.txt b/api/system-current.txt
index 227b483..30530a3 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1339,7 +1339,7 @@
package android.hardware.location {
- public class ContextHubInfo {
+ public class ContextHubInfo implements android.os.Parcelable {
ctor public ContextHubInfo();
method public int describeContents();
method public int getId();
@@ -4159,7 +4159,7 @@
method public deprecated boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
method public boolean needsOtaServiceProvisioning();
method public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
- method public void setDataEnabled(int, boolean);
+ method public deprecated void setDataEnabled(int, boolean);
method public boolean setRadio(boolean);
method public boolean setRadioPower(boolean);
method public deprecated void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
@@ -4605,6 +4605,7 @@
method public boolean canInvokeDrawGlFunctor(android.view.View);
method public void detachDrawGlFunctor(android.view.View, long);
method public android.app.Application getApplication();
+ method public java.lang.String getDataDirectorySuffix();
method public java.lang.String getErrorString(android.content.Context, int);
method public int getPackageId(android.content.res.Resources, java.lang.String);
method public void invokeDrawGlFunctor(android.view.View, long, boolean);
diff --git a/api/test-current.txt b/api/test-current.txt
index 5635b56..e64c320 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -326,6 +326,13 @@
field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
}
+ public class TrafficStats {
+ method public static long getLoopbackRxBytes();
+ method public static long getLoopbackRxPackets();
+ method public static long getLoopbackTxBytes();
+ method public static long getLoopbackTxPackets();
+ }
+
}
package android.os {
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index 4777dcd..162a34b 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -23,6 +23,7 @@
#include <android/os/IIncidentManager.h>
#include <android/os/IncidentReportArgs.h>
#include <binder/IServiceManager.h>
+#include <statslog.h>
#include <time.h>
namespace android {
@@ -224,6 +225,9 @@
}
StatsdStats::getInstance().noteAnomalyDeclared(mConfigKey, mAlert.name());
+
+ android::util::stats_write(android::util::ANOMALY_DETECTED, mConfigKey.GetUid(),
+ mConfigKey.GetName().c_str(), mAlert.name().c_str());
}
void AnomalyTracker::declareAnomalyIfAlarmExpired(const HashableDimensionKey& dimensionKey,
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index c37f05e..1c6d9b0 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -79,7 +79,8 @@
IsolatedUidChanged isolated_uid_changed = 43;
PacketWakeupOccurred packet_wakeup_occurred = 44;
DropboxErrorChanged dropbox_error_changed = 45;
- AppHook app_hook = 46;
+ AnomalyDetected anomaly_detected = 46;
+ AppHook app_hook = 47;
// TODO: Reorder the numbering so that the most frequent occur events occur in the first 15.
}
@@ -841,6 +842,23 @@
}
/**
+ * Logs when statsd detects an anomaly.
+ *
+ * Logged from:
+ * frameworks/base/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+ */
+message AnomalyDetected {
+ // Uid that owns the config whose anomaly detection alert fired.
+ optional int32 config_uid = 1;
+
+ // Name of the config whose anomaly detection alert fired.
+ optional string config_name = 2;
+
+ // Name of the alert (i.e. name of the anomaly that was detected).
+ optional string alert_name = 3;
+}
+
+/**
* Pulls bytes transferred via wifi (Sum of foreground and background usage).
*
* Pulled from:
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 200ef0b..5d0e97e 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -206,7 +206,7 @@
// clock will not grow very aggressive. New metrics will be delayed up to
// MIN_BUCKET_SIZE_SEC before starting.
long currentTimeSec = time(nullptr);
- uint64_t startTimeNs = (currentTimeSec + kMinBucketSizeSec -
+ uint64_t startTimeNs = (currentTimeSec - kMinBucketSizeSec -
(currentTimeSec - timeBaseSec) % kMinBucketSizeSec) *
NS_PER_SEC;
@@ -410,12 +410,15 @@
return false;
}
- if (((!metric.gauge_fields().has_include_all() ||
- (metric.gauge_fields().has_include_all() &&
- metric.gauge_fields().include_all() == false)) &&
- metric.gauge_fields().field_num_size() == 0) ||
- (metric.gauge_fields().has_include_all() && metric.gauge_fields().include_all() == true &&
- metric.gauge_fields().field_num_size() > 0)) {
+ if ((!metric.gauge_fields().has_include_all() ||
+ (metric.gauge_fields().include_all() == false)) &&
+ metric.gauge_fields().field_num_size() == 0) {
+ ALOGW("Incorrect field filter setting in GaugeMetric %s", metric.name().c_str());
+ return false;
+ }
+ if ((metric.gauge_fields().has_include_all() &&
+ metric.gauge_fields().include_all() == true) &&
+ metric.gauge_fields().field_num_size() > 0) {
ALOGW("Incorrect field filter setting in GaugeMetric %s", metric.name().c_str());
return false;
}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 847082a..1adae7a 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -457,6 +457,20 @@
/** @hide User operation call: one of related users cannot be stopped. */
public static final int USER_OP_ERROR_RELATED_USERS_CANNOT_STOP = -4;
+ /**
+ * @hide
+ * Process states, describing the kind of state a particular process is in.
+ * When updating these, make sure to also check all related references to the
+ * constant in code, and update these arrays:
+ *
+ * @see com.android.internal.app.procstats.ProcessState#PROCESS_STATE_TO_STATE
+ * @see com.android.server.am.ProcessList#sProcStateToProcMem
+ * @see com.android.server.am.ProcessList#sFirstAwakePssTimes
+ * @see com.android.server.am.ProcessList#sSameAwakePssTimes
+ * @see com.android.server.am.ProcessList#sTestFirstPssTimes
+ * @see com.android.server.am.ProcessList#sTestSamePssTimes
+ */
+
/** @hide Not a real process state. */
public static final int PROCESS_STATE_UNKNOWN = -1;
@@ -476,35 +490,35 @@
/** @hide Process is hosting a foreground service. */
public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;
- /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */
- public static final int PROCESS_STATE_TOP_SLEEPING = 5;
-
/** @hide Process is important to the user, and something they are aware of. */
- public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6;
+ public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 5;
/** @hide Process is important to the user, but not something they are aware of. */
- public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7;
+ public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 6;
/** @hide Process is in the background transient so we will try to keep running. */
- public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 8;
+ public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 7;
/** @hide Process is in the background running a backup/restore operation. */
- public static final int PROCESS_STATE_BACKUP = 9;
-
- /** @hide Process is in the background, but it can't restore its state so we want
- * to try to avoid killing it. */
- public static final int PROCESS_STATE_HEAVY_WEIGHT = 10;
+ public static final int PROCESS_STATE_BACKUP = 8;
/** @hide Process is in the background running a service. Unlike oom_adj, this level
* is used for both the normal running in background state and the executing
* operations state. */
- public static final int PROCESS_STATE_SERVICE = 11;
+ public static final int PROCESS_STATE_SERVICE = 9;
/** @hide Process is in the background running a receiver. Note that from the
* perspective of oom_adj, receivers run at a higher foreground level, but for our
* prioritization here that is not necessary and putting them below services means
* many fewer changes in some process states as they receive broadcasts. */
- public static final int PROCESS_STATE_RECEIVER = 12;
+ public static final int PROCESS_STATE_RECEIVER = 10;
+
+ /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */
+ public static final int PROCESS_STATE_TOP_SLEEPING = 11;
+
+ /** @hide Process is in the background, but it can't restore its state so we want
+ * to try to avoid killing it. */
+ public static final int PROCESS_STATE_HEAVY_WEIGHT = 12;
/** @hide Process is in the background but hosts the home activity. */
public static final int PROCESS_STATE_HOME = 13;
@@ -810,7 +824,7 @@
* impose on your application to let the overall system work best. The
* returned value is in megabytes; the baseline Android memory class is
* 16 (which happens to be the Java heap limit of those devices); some
- * device with more memory may return 24 or even higher numbers.
+ * devices with more memory may return 24 or even higher numbers.
*/
public int getMemoryClass() {
return staticGetMemoryClass();
@@ -837,7 +851,7 @@
* constrained devices, or it may be significantly larger on devices with
* a large amount of available RAM.
*
- * <p>The is the size of the application's Dalvik heap if it has
+ * <p>This is the size of the application's Dalvik heap if it has
* specified <code>android:largeHeap="true"</code> in its manifest.
*/
public int getLargeMemoryClass() {
@@ -2884,13 +2898,13 @@
public static final int IMPORTANCE_FOREGROUND_SERVICE = 125;
/**
- * Constant for {@link #importance}: This process is running the foreground
- * UI, but the device is asleep so it is not visible to the user. This means
- * the user is not really aware of the process, because they can not see or
- * interact with it, but it is quite important because it what they expect to
- * return to once unlocking the device.
+ * @deprecated Pre-{@link android.os.Build.VERSION_CODES#P} version of
+ * {@link #IMPORTANCE_TOP_SLEEPING}. As of Android
+ * {@link android.os.Build.VERSION_CODES#P}, this is considered much less
+ * important since we want to reduce what apps can do when the screen is off.
*/
- public static final int IMPORTANCE_TOP_SLEEPING = 150;
+ @Deprecated
+ public static final int IMPORTANCE_TOP_SLEEPING_PRE_28 = 150;
/**
* Constant for {@link #importance}: This process is running something
@@ -2942,14 +2956,6 @@
public static final int IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170;
/**
- * Constant for {@link #importance}: This process is running an
- * application that can not save its state, and thus can't be killed
- * while in the background. This will be used with apps that have
- * {@link android.R.attr#cantSaveState} set on their application tag.
- */
- public static final int IMPORTANCE_CANT_SAVE_STATE = 270;
-
- /**
* Constant for {@link #importance}: This process is contains services
* that should remain running. These are background services apps have
* started, not something the user is aware of, so they may be killed by
@@ -2959,6 +2965,23 @@
public static final int IMPORTANCE_SERVICE = 300;
/**
+ * Constant for {@link #importance}: This process is running the foreground
+ * UI, but the device is asleep so it is not visible to the user. Though the
+ * system will try hard to keep its process from being killed, in all other
+ * ways we consider it a kind of cached process, with the limitations that go
+ * along with that state: network access, running background services, etc.
+ */
+ public static final int IMPORTANCE_TOP_SLEEPING = 325;
+
+ /**
+ * Constant for {@link #importance}: This process is running an
+ * application that can not save its state, and thus can't be killed
+ * while in the background. This will be used with apps that have
+ * {@link android.R.attr#cantSaveState} set on their application tag.
+ */
+ public static final int IMPORTANCE_CANT_SAVE_STATE = 350;
+
+ /**
* Constant for {@link #importance}: This process process contains
* cached code that is expendable, not actively running any app components
* we care about.
@@ -2993,16 +3016,16 @@
return IMPORTANCE_GONE;
} else if (procState >= PROCESS_STATE_HOME) {
return IMPORTANCE_CACHED;
- } else if (procState >= PROCESS_STATE_SERVICE) {
- return IMPORTANCE_SERVICE;
} else if (procState == PROCESS_STATE_HEAVY_WEIGHT) {
return IMPORTANCE_CANT_SAVE_STATE;
+ } else if (procState >= PROCESS_STATE_TOP_SLEEPING) {
+ return IMPORTANCE_TOP_SLEEPING;
+ } else if (procState >= PROCESS_STATE_SERVICE) {
+ return IMPORTANCE_SERVICE;
} else if (procState >= PROCESS_STATE_TRANSIENT_BACKGROUND) {
return IMPORTANCE_PERCEPTIBLE;
} else if (procState >= PROCESS_STATE_IMPORTANT_FOREGROUND) {
return IMPORTANCE_VISIBLE;
- } else if (procState >= PROCESS_STATE_TOP_SLEEPING) {
- return IMPORTANCE_TOP_SLEEPING;
} else if (procState >= PROCESS_STATE_FOREGROUND_SERVICE) {
return IMPORTANCE_FOREGROUND_SERVICE;
} else {
@@ -3036,6 +3059,8 @@
switch (importance) {
case IMPORTANCE_PERCEPTIBLE:
return IMPORTANCE_PERCEPTIBLE_PRE_26;
+ case IMPORTANCE_TOP_SLEEPING:
+ return IMPORTANCE_TOP_SLEEPING_PRE_28;
case IMPORTANCE_CANT_SAVE_STATE:
return IMPORTANCE_CANT_SAVE_STATE_PRE_26;
}
@@ -3049,16 +3074,18 @@
return PROCESS_STATE_NONEXISTENT;
} else if (importance >= IMPORTANCE_CACHED) {
return PROCESS_STATE_HOME;
+ } else if (importance >= IMPORTANCE_CANT_SAVE_STATE) {
+ return PROCESS_STATE_HEAVY_WEIGHT;
+ } else if (importance >= IMPORTANCE_TOP_SLEEPING) {
+ return PROCESS_STATE_TOP_SLEEPING;
} else if (importance >= IMPORTANCE_SERVICE) {
return PROCESS_STATE_SERVICE;
- } else if (importance == IMPORTANCE_CANT_SAVE_STATE) {
- return PROCESS_STATE_HEAVY_WEIGHT;
} else if (importance >= IMPORTANCE_PERCEPTIBLE) {
return PROCESS_STATE_TRANSIENT_BACKGROUND;
} else if (importance >= IMPORTANCE_VISIBLE) {
return PROCESS_STATE_IMPORTANT_FOREGROUND;
- } else if (importance >= IMPORTANCE_TOP_SLEEPING) {
- return PROCESS_STATE_TOP_SLEEPING;
+ } else if (importance >= IMPORTANCE_TOP_SLEEPING_PRE_28) {
+ return PROCESS_STATE_FOREGROUND_SERVICE;
} else if (importance >= IMPORTANCE_FOREGROUND_SERVICE) {
return PROCESS_STATE_FOREGROUND_SERVICE;
} else {
@@ -3837,7 +3864,7 @@
pw.println();
dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { packageName });
pw.println();
- dumpService(pw, fd, "usagestats", new String[] { "--packages", packageName });
+ dumpService(pw, fd, "usagestats", new String[] { packageName });
pw.println();
dumpService(pw, fd, BatteryStats.SERVICE_NAME, new String[] { packageName });
pw.flush();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 84f032d..de346f3 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1152,7 +1152,7 @@
int N = stats.dbStats.size();
if (N > 0) {
pw.println(" DATABASES");
- printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
+ printRow(pw, DB_INFO_FORMAT, "pgsz", "dbsz", "Lookaside(b)", "cache",
"Dbname");
for (int i = 0; i < N; i++) {
DbStats dbStats = stats.dbStats.get(i);
@@ -1184,6 +1184,124 @@
}
@Override
+ public void dumpMemInfoProto(ParcelFileDescriptor pfd, Debug.MemoryInfo mem,
+ boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
+ boolean dumpUnreachable, String[] args) {
+ ProtoOutputStream proto = new ProtoOutputStream(pfd.getFileDescriptor());
+ try {
+ dumpMemInfo(proto, mem, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable);
+ } finally {
+ proto.flush();
+ IoUtils.closeQuietly(pfd);
+ }
+ }
+
+ private void dumpMemInfo(ProtoOutputStream proto, Debug.MemoryInfo memInfo,
+ boolean dumpFullInfo, boolean dumpDalvik,
+ boolean dumpSummaryOnly, boolean dumpUnreachable) {
+ long nativeMax = Debug.getNativeHeapSize() / 1024;
+ long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
+ long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
+
+ Runtime runtime = Runtime.getRuntime();
+ runtime.gc(); // Do GC since countInstancesOfClass counts unreachable objects.
+ long dalvikMax = runtime.totalMemory() / 1024;
+ long dalvikFree = runtime.freeMemory() / 1024;
+ long dalvikAllocated = dalvikMax - dalvikFree;
+
+ Class[] classesToCount = new Class[] {
+ ContextImpl.class,
+ Activity.class,
+ WebView.class,
+ OpenSSLSocketImpl.class
+ };
+ long[] instanceCounts = VMDebug.countInstancesOfClasses(classesToCount, true);
+ long appContextInstanceCount = instanceCounts[0];
+ long activityInstanceCount = instanceCounts[1];
+ long webviewInstanceCount = instanceCounts[2];
+ long openSslSocketCount = instanceCounts[3];
+
+ long viewInstanceCount = ViewDebug.getViewInstanceCount();
+ long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
+ int globalAssetCount = AssetManager.getGlobalAssetCount();
+ int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
+ int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
+ int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
+ int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
+ long parcelSize = Parcel.getGlobalAllocSize();
+ long parcelCount = Parcel.getGlobalAllocCount();
+ SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
+
+ final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
+ proto.write(MemInfoProto.ProcessMemory.PID, Process.myPid());
+ proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME,
+ (mBoundApplication != null) ? mBoundApplication.processName : "unknown");
+ dumpMemInfoTable(proto, memInfo, dumpDalvik, dumpSummaryOnly,
+ nativeMax, nativeAllocated, nativeFree,
+ dalvikMax, dalvikAllocated, dalvikFree);
+ proto.end(mToken);
+
+ final long oToken = proto.start(MemInfoProto.AppData.OBJECTS);
+ proto.write(MemInfoProto.AppData.ObjectStats.VIEW_INSTANCE_COUNT, viewInstanceCount);
+ proto.write(MemInfoProto.AppData.ObjectStats.VIEW_ROOT_INSTANCE_COUNT,
+ viewRootInstanceCount);
+ proto.write(MemInfoProto.AppData.ObjectStats.APP_CONTEXT_INSTANCE_COUNT,
+ appContextInstanceCount);
+ proto.write(MemInfoProto.AppData.ObjectStats.ACTIVITY_INSTANCE_COUNT,
+ activityInstanceCount);
+ proto.write(MemInfoProto.AppData.ObjectStats.GLOBAL_ASSET_COUNT, globalAssetCount);
+ proto.write(MemInfoProto.AppData.ObjectStats.GLOBAL_ASSET_MANAGER_COUNT,
+ globalAssetManagerCount);
+ proto.write(MemInfoProto.AppData.ObjectStats.LOCAL_BINDER_OBJECT_COUNT,
+ binderLocalObjectCount);
+ proto.write(MemInfoProto.AppData.ObjectStats.PROXY_BINDER_OBJECT_COUNT,
+ binderProxyObjectCount);
+ proto.write(MemInfoProto.AppData.ObjectStats.PARCEL_MEMORY_KB, parcelSize / 1024);
+ proto.write(MemInfoProto.AppData.ObjectStats.PARCEL_COUNT, parcelCount);
+ proto.write(MemInfoProto.AppData.ObjectStats.BINDER_OBJECT_DEATH_COUNT,
+ binderDeathObjectCount);
+ proto.write(MemInfoProto.AppData.ObjectStats.OPEN_SSL_SOCKET_COUNT, openSslSocketCount);
+ proto.write(MemInfoProto.AppData.ObjectStats.WEBVIEW_INSTANCE_COUNT,
+ webviewInstanceCount);
+ proto.end(oToken);
+
+ // SQLite mem info
+ final long sToken = proto.start(MemInfoProto.AppData.SQL);
+ proto.write(MemInfoProto.AppData.SqlStats.MEMORY_USED_KB, stats.memoryUsed / 1024);
+ proto.write(MemInfoProto.AppData.SqlStats.PAGECACHE_OVERFLOW_KB,
+ stats.pageCacheOverflow / 1024);
+ proto.write(MemInfoProto.AppData.SqlStats.MALLOC_SIZE_KB, stats.largestMemAlloc / 1024);
+ int n = stats.dbStats.size();
+ for (int i = 0; i < n; i++) {
+ DbStats dbStats = stats.dbStats.get(i);
+
+ final long dToken = proto.start(MemInfoProto.AppData.SqlStats.DATABASES);
+ proto.write(MemInfoProto.AppData.SqlStats.Database.NAME, dbStats.dbName);
+ proto.write(MemInfoProto.AppData.SqlStats.Database.PAGE_SIZE, dbStats.pageSize);
+ proto.write(MemInfoProto.AppData.SqlStats.Database.DB_SIZE, dbStats.dbSize);
+ proto.write(MemInfoProto.AppData.SqlStats.Database.LOOKASIDE_B, dbStats.lookaside);
+ proto.write(MemInfoProto.AppData.SqlStats.Database.CACHE, dbStats.cache);
+ proto.end(dToken);
+ }
+ proto.end(sToken);
+
+ // Asset details.
+ String assetAlloc = AssetManager.getAssetAllocations();
+ if (assetAlloc != null) {
+ proto.write(MemInfoProto.AppData.ASSET_ALLOCATIONS, assetAlloc);
+ }
+
+ // Unreachable native memory
+ if (dumpUnreachable) {
+ int flags = mBoundApplication == null ? 0 : mBoundApplication.appInfo.flags;
+ boolean showContents = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0
+ || android.os.Build.IS_DEBUGGABLE;
+ proto.write(MemInfoProto.AppData.UNREACHABLE_MEMORY,
+ Debug.getUnreachableMemory(100, showContents));
+ }
+ }
+
+ @Override
public void dumpGfxInfo(ParcelFileDescriptor pfd, String[] args) {
nDumpGraphicsInfo(pfd.getFileDescriptor());
WindowManagerGlobal.getInstance().dumpGfxInfo(pfd.getFileDescriptor(), args);
@@ -2335,23 +2453,23 @@
*
* @param hasSwappedOutPss determines whether to use dirtySwap or dirtySwapPss
*/
- private static void dumpHeap(ProtoOutputStream proto, long fieldId, String name,
+ private static void dumpMemoryInfo(ProtoOutputStream proto, long fieldId, String name,
int pss, int cleanPss, int sharedDirty, int privateDirty,
int sharedClean, int privateClean,
boolean hasSwappedOutPss, int dirtySwap, int dirtySwapPss) {
final long token = proto.start(fieldId);
- proto.write(MemInfoProto.NativeProcess.MemoryInfo.NAME, name);
- proto.write(MemInfoProto.NativeProcess.MemoryInfo.TOTAL_PSS_KB, pss);
- proto.write(MemInfoProto.NativeProcess.MemoryInfo.CLEAN_PSS_KB, cleanPss);
- proto.write(MemInfoProto.NativeProcess.MemoryInfo.SHARED_DIRTY_KB, sharedDirty);
- proto.write(MemInfoProto.NativeProcess.MemoryInfo.PRIVATE_DIRTY_KB, privateDirty);
- proto.write(MemInfoProto.NativeProcess.MemoryInfo.SHARED_CLEAN_KB, sharedClean);
- proto.write(MemInfoProto.NativeProcess.MemoryInfo.PRIVATE_CLEAN_KB, privateClean);
+ proto.write(MemInfoProto.ProcessMemory.MemoryInfo.NAME, name);
+ proto.write(MemInfoProto.ProcessMemory.MemoryInfo.TOTAL_PSS_KB, pss);
+ proto.write(MemInfoProto.ProcessMemory.MemoryInfo.CLEAN_PSS_KB, cleanPss);
+ proto.write(MemInfoProto.ProcessMemory.MemoryInfo.SHARED_DIRTY_KB, sharedDirty);
+ proto.write(MemInfoProto.ProcessMemory.MemoryInfo.PRIVATE_DIRTY_KB, privateDirty);
+ proto.write(MemInfoProto.ProcessMemory.MemoryInfo.SHARED_CLEAN_KB, sharedClean);
+ proto.write(MemInfoProto.ProcessMemory.MemoryInfo.PRIVATE_CLEAN_KB, privateClean);
if (hasSwappedOutPss) {
- proto.write(MemInfoProto.NativeProcess.MemoryInfo.DIRTY_SWAP_PSS_KB, dirtySwapPss);
+ proto.write(MemInfoProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_PSS_KB, dirtySwapPss);
} else {
- proto.write(MemInfoProto.NativeProcess.MemoryInfo.DIRTY_SWAP_KB, dirtySwap);
+ proto.write(MemInfoProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_KB, dirtySwap);
}
proto.end(token);
@@ -2366,26 +2484,26 @@
long dalvikMax, long dalvikAllocated, long dalvikFree) {
if (!dumpSummaryOnly) {
- final long nhToken = proto.start(MemInfoProto.NativeProcess.NATIVE_HEAP);
- dumpHeap(proto, MemInfoProto.NativeProcess.HeapInfo.MEM_INFO, "Native Heap",
+ final long nhToken = proto.start(MemInfoProto.ProcessMemory.NATIVE_HEAP);
+ dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.HeapInfo.MEM_INFO, "Native Heap",
memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
memInfo.nativePrivateClean, memInfo.hasSwappedOutPss,
memInfo.nativeSwappedOut, memInfo.nativeSwappedOutPss);
- proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_SIZE_KB, nativeMax);
- proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_ALLOC_KB, nativeAllocated);
- proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_FREE_KB, nativeFree);
+ proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, nativeMax);
+ proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, nativeAllocated);
+ proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, nativeFree);
proto.end(nhToken);
- final long dvToken = proto.start(MemInfoProto.NativeProcess.DALVIK_HEAP);
- dumpHeap(proto, MemInfoProto.NativeProcess.HeapInfo.MEM_INFO, "Dalvik Heap",
+ final long dvToken = proto.start(MemInfoProto.ProcessMemory.DALVIK_HEAP);
+ dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.HeapInfo.MEM_INFO, "Dalvik Heap",
memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss,
memInfo.dalvikSwappedOut, memInfo.dalvikSwappedOutPss);
- proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_SIZE_KB, dalvikMax);
- proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_ALLOC_KB, dalvikAllocated);
- proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_FREE_KB, dalvikFree);
+ proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, dalvikMax);
+ proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, dalvikAllocated);
+ proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, dalvikFree);
proto.end(dvToken);
int otherPss = memInfo.otherPss;
@@ -2409,7 +2527,7 @@
if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
|| mySharedClean != 0 || myPrivateClean != 0
|| (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
- dumpHeap(proto, MemInfoProto.NativeProcess.OTHER_HEAPS,
+ dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.OTHER_HEAPS,
Debug.MemoryInfo.getOtherLabel(i),
myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
mySharedClean, myPrivateClean,
@@ -2426,21 +2544,21 @@
}
}
- dumpHeap(proto, MemInfoProto.NativeProcess.UNKNOWN_HEAP, "Unknown",
+ dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.UNKNOWN_HEAP, "Unknown",
otherPss, otherSwappablePss,
otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
memInfo.hasSwappedOutPss, otherSwappedOut, otherSwappedOutPss);
- final long tToken = proto.start(MemInfoProto.NativeProcess.TOTAL_HEAP);
- dumpHeap(proto, MemInfoProto.NativeProcess.HeapInfo.MEM_INFO, "TOTAL",
+ final long tToken = proto.start(MemInfoProto.ProcessMemory.TOTAL_HEAP);
+ dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.HeapInfo.MEM_INFO, "TOTAL",
memInfo.getTotalPss(), memInfo.getTotalSwappablePss(),
memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
memInfo.hasSwappedOutPss, memInfo.getTotalSwappedOut(),
memInfo.getTotalSwappedOutPss());
- proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_SIZE_KB, nativeMax + dalvikMax);
- proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_ALLOC_KB,
+ proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, nativeMax + dalvikMax);
+ proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB,
nativeAllocated + dalvikAllocated);
- proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_FREE_KB, nativeFree + dalvikFree);
+ proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, nativeFree + dalvikFree);
proto.end(tToken);
if (dumpDalvik) {
@@ -2458,7 +2576,7 @@
if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
|| mySharedClean != 0 || myPrivateClean != 0
|| (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
- dumpHeap(proto, MemInfoProto.NativeProcess.DALVIK_DETAILS,
+ dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.DALVIK_DETAILS,
Debug.MemoryInfo.getOtherLabel(i),
myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
mySharedClean, myPrivateClean,
@@ -2468,24 +2586,24 @@
}
}
- final long asToken = proto.start(MemInfoProto.NativeProcess.APP_SUMMARY);
- proto.write(MemInfoProto.NativeProcess.AppSummary.JAVA_HEAP_PSS_KB,
+ final long asToken = proto.start(MemInfoProto.ProcessMemory.APP_SUMMARY);
+ proto.write(MemInfoProto.ProcessMemory.AppSummary.JAVA_HEAP_PSS_KB,
memInfo.getSummaryJavaHeap());
- proto.write(MemInfoProto.NativeProcess.AppSummary.NATIVE_HEAP_PSS_KB,
+ proto.write(MemInfoProto.ProcessMemory.AppSummary.NATIVE_HEAP_PSS_KB,
memInfo.getSummaryNativeHeap());
- proto.write(MemInfoProto.NativeProcess.AppSummary.CODE_PSS_KB, memInfo.getSummaryCode());
- proto.write(MemInfoProto.NativeProcess.AppSummary.STACK_PSS_KB, memInfo.getSummaryStack());
- proto.write(MemInfoProto.NativeProcess.AppSummary.GRAPHICS_PSS_KB,
+ proto.write(MemInfoProto.ProcessMemory.AppSummary.CODE_PSS_KB, memInfo.getSummaryCode());
+ proto.write(MemInfoProto.ProcessMemory.AppSummary.STACK_PSS_KB, memInfo.getSummaryStack());
+ proto.write(MemInfoProto.ProcessMemory.AppSummary.GRAPHICS_PSS_KB,
memInfo.getSummaryGraphics());
- proto.write(MemInfoProto.NativeProcess.AppSummary.PRIVATE_OTHER_PSS_KB,
+ proto.write(MemInfoProto.ProcessMemory.AppSummary.PRIVATE_OTHER_PSS_KB,
memInfo.getSummaryPrivateOther());
- proto.write(MemInfoProto.NativeProcess.AppSummary.SYSTEM_PSS_KB,
+ proto.write(MemInfoProto.ProcessMemory.AppSummary.SYSTEM_PSS_KB,
memInfo.getSummarySystem());
if (memInfo.hasSwappedOutPss) {
- proto.write(MemInfoProto.NativeProcess.AppSummary.TOTAL_SWAP_PSS,
+ proto.write(MemInfoProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
memInfo.getSummaryTotalSwapPss());
} else {
- proto.write(MemInfoProto.NativeProcess.AppSummary.TOTAL_SWAP_PSS,
+ proto.write(MemInfoProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
memInfo.getSummaryTotalSwap());
}
proto.end(asToken);
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index b25d778..893a41c 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -110,6 +110,9 @@
void dumpMemInfo(in ParcelFileDescriptor fd, in Debug.MemoryInfo mem, boolean checkin,
boolean dumpInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable,
in String[] args);
+ void dumpMemInfoProto(in ParcelFileDescriptor fd, in Debug.MemoryInfo mem,
+ boolean dumpInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable,
+ in String[] args);
void dumpGfxInfo(in ParcelFileDescriptor fd, in String[] args);
void dumpProvider(in ParcelFileDescriptor fd, IBinder servicetoken,
in String[] args);
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 49d58eb..80782e3 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -155,4 +155,9 @@
* Unregister a callback that was receiving color updates
*/
void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId);
+
+ /**
+ * Called from SystemUI when it shows the AoD UI.
+ */
+ void setInAmbientMode(boolean inAmbienMode);
}
diff --git a/core/java/android/app/WallpaperInfo.java b/core/java/android/app/WallpaperInfo.java
index 9d40381f..35a1789 100644
--- a/core/java/android/app/WallpaperInfo.java
+++ b/core/java/android/app/WallpaperInfo.java
@@ -16,18 +16,15 @@
package android.app;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources.NotFoundException;
import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
@@ -39,6 +36,9 @@
import android.util.Printer;
import android.util.Xml;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.IOException;
/**
@@ -76,6 +76,7 @@
final int mContextUriResource;
final int mContextDescriptionResource;
final boolean mShowMetadataInPreview;
+ final boolean mSupportsAmbientMode;
/**
* Constructor.
@@ -89,15 +90,7 @@
mService = service;
ServiceInfo si = service.serviceInfo;
- PackageManager pm = context.getPackageManager();
- String settingsActivityComponent = null;
- int thumbnailRes = -1;
- int authorRes = -1;
- int descriptionRes = -1;
- int contextUriRes = -1;
- int contextDescriptionRes = -1;
- boolean showMetadataInPreview = false;
-
+ final PackageManager pm = context.getPackageManager();
XmlResourceParser parser = null;
try {
parser = si.loadXmlMetaData(pm, WallpaperService.SERVICE_META_DATA);
@@ -123,27 +116,30 @@
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.Wallpaper);
- settingsActivityComponent = sa.getString(
+ mSettingsActivityName = sa.getString(
com.android.internal.R.styleable.Wallpaper_settingsActivity);
-
- thumbnailRes = sa.getResourceId(
+
+ mThumbnailResource = sa.getResourceId(
com.android.internal.R.styleable.Wallpaper_thumbnail,
-1);
- authorRes = sa.getResourceId(
+ mAuthorResource = sa.getResourceId(
com.android.internal.R.styleable.Wallpaper_author,
-1);
- descriptionRes = sa.getResourceId(
+ mDescriptionResource = sa.getResourceId(
com.android.internal.R.styleable.Wallpaper_description,
-1);
- contextUriRes = sa.getResourceId(
+ mContextUriResource = sa.getResourceId(
com.android.internal.R.styleable.Wallpaper_contextUri,
-1);
- contextDescriptionRes = sa.getResourceId(
+ mContextDescriptionResource = sa.getResourceId(
com.android.internal.R.styleable.Wallpaper_contextDescription,
-1);
- showMetadataInPreview = sa.getBoolean(
+ mShowMetadataInPreview = sa.getBoolean(
com.android.internal.R.styleable.Wallpaper_showMetadataInPreview,
false);
+ mSupportsAmbientMode = sa.getBoolean(
+ com.android.internal.R.styleable.Wallpaper_supportsAmbientMode,
+ false);
sa.recycle();
} catch (NameNotFoundException e) {
@@ -152,14 +148,6 @@
} finally {
if (parser != null) parser.close();
}
-
- mSettingsActivityName = settingsActivityComponent;
- mThumbnailResource = thumbnailRes;
- mAuthorResource = authorRes;
- mDescriptionResource = descriptionRes;
- mContextUriResource = contextUriRes;
- mContextDescriptionResource = contextDescriptionRes;
- mShowMetadataInPreview = showMetadataInPreview;
}
WallpaperInfo(Parcel source) {
@@ -170,6 +158,7 @@
mContextUriResource = source.readInt();
mContextDescriptionResource = source.readInt();
mShowMetadataInPreview = source.readInt() != 0;
+ mSupportsAmbientMode = source.readInt() != 0;
mService = ResolveInfo.CREATOR.createFromParcel(source);
}
@@ -326,6 +315,16 @@
}
/**
+ * Returns whether a wallpaper was optimized or not for ambient mode.
+ *
+ * @return {@code true} if wallpaper can draw in ambient mode.
+ * @hide
+ */
+ public boolean getSupportsAmbientMode() {
+ return mSupportsAmbientMode;
+ }
+
+ /**
* Return the class name of an activity that provides a settings UI for
* the wallpaper. You can launch this activity be starting it with
* an {@link android.content.Intent} whose action is MAIN and with an
@@ -366,6 +365,7 @@
dest.writeInt(mContextUriResource);
dest.writeInt(mContextDescriptionResource);
dest.writeInt(mShowMetadataInPreview ? 1 : 0);
+ dest.writeInt(mSupportsAmbientMode ? 1 : 0);
mService.writeToParcel(dest, flags);
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 89df421..9ad990a 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2635,10 +2635,121 @@
}
/**
+ * The maximum number of characters allowed in the password blacklist.
+ */
+ private static final int PASSWORD_BLACKLIST_CHARACTER_LIMIT = 128 * 1000;
+
+ /**
+ * Throws an exception if the password blacklist is too large.
+ *
+ * @hide
+ */
+ public static void enforcePasswordBlacklistSize(List<String> blacklist) {
+ if (blacklist == null) {
+ return;
+ }
+ long characterCount = 0;
+ for (final String item : blacklist) {
+ characterCount += item.length();
+ }
+ if (characterCount > PASSWORD_BLACKLIST_CHARACTER_LIMIT) {
+ throw new IllegalArgumentException("128 thousand blacklist character limit exceeded by "
+ + (characterCount - PASSWORD_BLACKLIST_CHARACTER_LIMIT) + " characters");
+ }
+ }
+
+ /**
+ * Called by an application that is administering the device to blacklist passwords.
+ * <p>
+ * Any blacklisted password or PIN is prevented from being enrolled by the user or the admin.
+ * Note that the match against the blacklist is case insensitive. The blacklist applies for all
+ * password qualities requested by {@link #setPasswordQuality} however it is not taken into
+ * consideration by {@link #isActivePasswordSufficient}.
+ * <p>
+ * The blacklist can be cleared by passing {@code null} or an empty list. The blacklist is
+ * given a name that is used to track which blacklist is currently set by calling {@link
+ * #getPasswordBlacklistName}. If the blacklist is being cleared, the name is ignored and {@link
+ * #getPasswordBlacklistName} will return {@code null}. The name can only be {@code null} when
+ * the blacklist is being cleared.
+ * <p>
+ * The blacklist is limited to a total of 128 thousand characters rather than limiting to a
+ * number of entries.
+ * <p>
+ * This method can be called on the {@link DevicePolicyManager} instance returned by
+ * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
+ * profile.
+ *
+ * @param admin the {@link DeviceAdminReceiver} this request is associated with
+ * @param name name to associate with the blacklist
+ * @param blacklist list of passwords to blacklist or {@code null} to clear the blacklist
+ * @return whether the new blacklist was successfully installed
+ * @throws SecurityException if {@code admin} is not a device or profile owner
+ * @throws IllegalArgumentException if the blacklist surpasses the character limit
+ * @throws NullPointerException if {@code name} is {@code null} when setting a non-empty list
+ *
+ * @see #getPasswordBlacklistName
+ * @see #isActivePasswordSufficient
+ * @see #resetPasswordWithToken
+ *
+ * TODO(63578054): unhide for P
+ * @hide
+ */
+ public boolean setPasswordBlacklist(@NonNull ComponentName admin, @Nullable String name,
+ @Nullable List<String> blacklist) {
+ enforcePasswordBlacklistSize(blacklist);
+
+ try {
+ return mService.setPasswordBlacklist(admin, name, blacklist, mParentInstance);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Get the name of the password blacklist set by the given admin.
+ *
+ * @param admin the {@link DeviceAdminReceiver} this request is associated with
+ * @return the name of the blacklist or {@code null} if no blacklist is set
+ *
+ * @see #setPasswordBlacklist
+ *
+ * TODO(63578054): unhide for P
+ * @hide
+ */
+ public @Nullable String getPasswordBlacklistName(@NonNull ComponentName admin) {
+ try {
+ return mService.getPasswordBlacklistName(admin, myUserId(), mParentInstance);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Test if a given password is blacklisted.
+ *
+ * @param userId the user to valiate for
+ * @param password the password to check against the blacklist
+ * @return whether the password is blacklisted
+ *
+ * @see #setPasswordBlacklist
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.TEST_BLACKLISTED_PASSWORD)
+ public boolean isPasswordBlacklisted(@UserIdInt int userId, @NonNull String password) {
+ try {
+ return mService.isPasswordBlacklisted(userId, password);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Determine whether the current password the user has set is sufficient to meet the policy
* requirements (e.g. quality, minimum length) that have been requested by the admins of this
* user and its participating profiles. Restrictions on profiles that have a separate challenge
- * are not taken into account. The user must be unlocked in order to perform the check.
+ * are not taken into account. The user must be unlocked in order to perform the check. The
+ * password blacklist is not considered when checking sufficiency.
* <p>
* The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
@@ -2676,6 +2787,7 @@
* @see UserManager#DISALLOW_UNIFIED_PASSWORD
*/
public boolean isUsingUnifiedPassword(@NonNull ComponentName admin) {
+ throwIfParentInstance("isUsingUnifiedPassword");
if (mService != null) {
try {
return mService.isUsingUnifiedPassword(admin);
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 9128208..f4cd797 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -78,6 +78,10 @@
long getPasswordExpiration(in ComponentName who, int userHandle, boolean parent);
+ boolean setPasswordBlacklist(in ComponentName who, String name, in List<String> blacklist, boolean parent);
+ String getPasswordBlacklistName(in ComponentName who, int userId, boolean parent);
+ boolean isPasswordBlacklisted(int userId, String password);
+
boolean isActivePasswordSufficient(int userHandle, boolean parent);
boolean isProfileActivePasswordSufficientForParent(int userHandle);
boolean isUsingUnifiedPassword(in ComponentName admin);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e2fd82d..21e203b 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -87,7 +87,6 @@
import android.util.TypedValue;
import android.util.apk.ApkSignatureSchemeV2Verifier;
import android.util.apk.ApkSignatureVerifier;
-import android.util.apk.SignatureNotFoundException;
import android.view.Gravity;
import com.android.internal.R;
@@ -1561,41 +1560,35 @@
boolean systemDir = (parseFlags & PARSE_IS_SYSTEM_DIR) != 0;
int minSignatureScheme = ApkSignatureVerifier.VERSION_JAR_SIGNATURE_SCHEME;
- if ((parseFlags & PARSE_IS_EPHEMERAL) != 0 || pkg.applicationInfo.isStaticSharedLibrary()) {
+ if (pkg.applicationInfo.isStaticSharedLibrary()) {
// must use v2 signing scheme
minSignatureScheme = ApkSignatureVerifier.VERSION_APK_SIGNATURE_SCHEME_V2;
}
- try {
- ApkSignatureVerifier.Result verified =
- ApkSignatureVerifier.verify(apkPath, minSignatureScheme, systemDir);
- if (pkg.mCertificates == null) {
- pkg.mCertificates = verified.certs;
- pkg.mSignatures = verified.sigs;
- pkg.mSigningKeys = new ArraySet<>(verified.certs.length);
- for (int i = 0; i < verified.certs.length; i++) {
- Certificate[] signerCerts = verified.certs[i];
- Certificate signerCert = signerCerts[0];
- pkg.mSigningKeys.add(signerCert.getPublicKey());
- }
- } else {
- if (!Signature.areExactMatch(pkg.mSignatures, verified.sigs)) {
- throw new PackageParserException(
- INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
- apkPath + " has mismatched certificates");
- }
- }
- } catch (SignatureNotFoundException e) {
+ ApkSignatureVerifier.Result verified =
+ ApkSignatureVerifier.verify(apkPath, minSignatureScheme, systemDir);
+ if (verified.signatureSchemeVersion
+ < ApkSignatureVerifier.VERSION_APK_SIGNATURE_SCHEME_V2) {
+ // TODO (b/68860689): move this logic to packagemanagerserivce
if ((parseFlags & PARSE_IS_EPHEMERAL) != 0) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
- "No APK Signature Scheme v2 signature in ephemeral package " + apkPath,
- e);
+ "No APK Signature Scheme v2 signature in ephemeral package " + apkPath);
}
- if (pkg.applicationInfo.isStaticSharedLibrary()) {
- throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
- "Static shared libs must use v2 signature scheme " + apkPath);
+ }
+ if (pkg.mCertificates == null) {
+ pkg.mCertificates = verified.certs;
+ pkg.mSignatures = verified.sigs;
+ pkg.mSigningKeys = new ArraySet<>(verified.certs.length);
+ for (int i = 0; i < verified.certs.length; i++) {
+ Certificate[] signerCerts = verified.certs[i];
+ Certificate signerCert = signerCerts[0];
+ pkg.mSigningKeys.add(signerCert.getPublicKey());
}
- throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
- "No APK Signature Scheme v2 signature in package " + apkPath, e);
+ } else {
+ if (!Signature.areExactMatch(pkg.mSignatures, verified.sigs)) {
+ throw new PackageParserException(
+ INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
+ apkPath + " has mismatched certificates");
+ }
}
}
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index 8623524..30222b7 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -39,9 +39,9 @@
* The ShortcutManager performs operations on an app's set of <em>shortcuts</em>. The
* {@link ShortcutInfo} class contains information about each of the shortcuts themselves.
*
- * <p>An app's shortcuts represent specific tasks and actions that users can take within your app.
- * When a user selects a shortcut in the currently-active launcher, your app opens an activity other
- * than the app's starting activity, provided that the currently-active launcher supports app
+ * <p>An app's shortcuts represent specific tasks and actions that users can perform within your
+ * app. When a user selects a shortcut in the currently-active launcher, your app opens an activity
+ * other than the app's starting activity, provided that the currently-active launcher supports app
* shortcuts.</p>
*
* <p>The types of shortcuts that you create for your app depend on the app's key use cases. For
@@ -94,13 +94,15 @@
*
* <p>When the launcher displays an app's shortcuts, they should appear in the following order:
*
- * <ul>
- * <li>Static shortcuts—shortcuts whose {@link ShortcutInfo#isDeclaredInManifest()} method
- * returns {@code true}—followed by dynamic shortcuts—shortcuts whose
- * {@link ShortcutInfo#isDynamic()} method returns {@code true}.
- * <li>Within each shortcut type (static and dynamic), shortcuts are sorted in order of increasing
- * rank according to {@link ShortcutInfo#getRank()}.
- * </ul>
+ * <ol>
+ * <li><b>Static shortcuts:</b> Shortcuts whose {@link ShortcutInfo#isDeclaredInManifest()} method
+ * returns {@code true}.</li>
+ * <li><b>Dynamic shortcuts:</b> Shortcuts whose {@link ShortcutInfo#isDynamic()} method returns
+ * {@code true}.</li>
+ * </ol>
+ *
+ * <p>Within each shortcut type (static and dynamic), shortcuts are sorted in order of increasing
+ * rank according to {@link ShortcutInfo#getRank()}.</p>
*
* <h4>Shortcut ranks</h4>
*
@@ -118,8 +120,8 @@
* <h3>Options for static shortcuts</h3>
*
* The following list includes descriptions for the different attributes within a static shortcut.
- * You must provide a value for {@code android:shortcutId}, {@code android:shortcutShortLabel}; all
- * other values are optional.
+ * You must provide a value for {@code android:shortcutId} and {@code android:shortcutShortLabel};
+ * all other values are optional.
*
* <dl>
* <dt>{@code android:shortcutId}</dt>
@@ -134,7 +136,7 @@
* <p>The default value is {@code true}. If you set it to {@code false}, you should also set
* {@code android:shortcutDisabledMessage} to a message that explains why you've disabled the
* shortcut. If you don't think you need to provide such a message, it's easiest to just remove
- * the shortcut from the XML file entirely, rather than changing the values of its
+ * the shortcut from the XML file entirely, rather than changing the values of the shortcut's
* {@code android:enabled} and {@code android:shortcutDisabledMessage} attributes.
* </dd>
*
@@ -152,7 +154,7 @@
* <dd><p>A concise phrase that describes the shortcut's purpose. For more information, see
* {@link ShortcutInfo.Builder#setShortLabel(CharSequence)}.</p>
* <p class="note"><b>Note: </b>This attribute's value must be a resource string, such as
- * <code>@string/shortcut_label</code>.</p>
+ * <code>@string/shortcut_short_label</code>.</p>
* </dd>
*
* <dt>{@code android:shortcutLongLabel}</dt>
@@ -165,8 +167,8 @@
*
* <dt>{@code android:shortcutDisabledMessage}</dt>
* <dd><p>The message that appears in a supported launcher when the user attempts to launch a
- * disabled shortcut. This attribute's value has no effect if {@code android:enabled} is
- * {@code true}. The message should explain to the user why the shortcut is now disabled.</p>
+ * disabled shortcut. The message should explain to the user why the shortcut is now disabled.
+ * This attribute's value has no effect if {@code android:enabled} is {@code true}.</p>
* <p class="note"><b>Note: </b>This attribute's value must be a resource string, such as
* <code>@string/shortcut_disabled_message</code>.</p>
* </dd>
@@ -175,20 +177,20 @@
* <h3>Inner elements that define static shortcuts</h3>
*
* <p>The XML file that lists an app's static shortcuts supports the following elements inside each
- * {@code <shortcut>} element. You must include an {@code intent} inner element for each
+ * {@code <shortcut>} element. You must include an {@code intent} inner element for each
* static shortcut that you define.</p>
*
* <dl>
* <dt>{@code intent}</dt>
* <dd><p>The action that the system launches when the user selects the shortcut. This intent must
* provide a value for the {@code android:action} attribute.</p>
- * <p>You can provide multiple intents for a single shortcut so that the last defined activity is
- * launched with the other activities in the
+ * <p>You can provide multiple intents for a single shortcut. If you do so, the last defined
+ * activity is launched, and the other activities are placed in the
* <a href="/guide/components/tasks-and-back-stack.html">back stack</a>. See
* <a href="/guide/topics/ui/shortcuts.html#static">Using Static Shortcuts</a> and the
* {@link android.app.TaskStackBuilder} class reference for details.</p>
* <p class="note"><b>Note:</b> This {@code intent} element cannot include string resources.</p>
- * <p>For more information, see
+ * <p>To learn more about how to configure intents, see
* <a href="{@docRoot}guide/topics/ui/settings.html#Intents">Using intents</a>.</p>
* </dd>
*
diff --git a/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java b/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java
index e02e68d..5bf3a7c 100644
--- a/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java
+++ b/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java
@@ -37,7 +37,7 @@
private static final String TAG = "SQLiteCompatibilityWalFlags";
- private static volatile boolean sInitialized = true; // Temporarily disable flags
+ private static volatile boolean sInitialized;
private static volatile boolean sFlagsSet;
private static volatile boolean sCompatibilityWalSupported;
private static volatile String sWALSyncMode;
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java
index e1137aa..c25f151 100644
--- a/core/java/android/hardware/location/ContextHubInfo.java
+++ b/core/java/android/hardware/location/ContextHubInfo.java
@@ -26,7 +26,7 @@
* @hide
*/
@SystemApi
-public class ContextHubInfo {
+public class ContextHubInfo implements Parcelable {
private int mId;
private String mName;
private String mVendor;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 8071e8b..11d338d 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1794,7 +1794,7 @@
ITelephony it = ITelephony.Stub.asInterface(b);
int subId = SubscriptionManager.getDefaultDataSubscriptionId();
Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
- boolean retVal = it.getDataEnabled(subId);
+ boolean retVal = it.isUserDataEnabled(subId);
Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
+ " retVal=" + retVal);
return retVal;
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index 954e59c..d701550 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -19,6 +19,7 @@
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.DownloadManager;
import android.app.backup.BackupManager;
import android.app.usage.NetworkStatsManager;
@@ -154,6 +155,8 @@
private static Object sProfilingLock = new Object();
+ private static final String LOOPBACK_IFACE = "lo";
+
/**
* Set active tag to use when accounting {@link Socket} traffic originating
* from the current thread. Only one active tag per thread is supported.
@@ -542,6 +545,30 @@
return nativeGetIfaceStat(iface, TYPE_RX_BYTES);
}
+ /** {@hide} */
+ @TestApi
+ public static long getLoopbackTxPackets() {
+ return nativeGetIfaceStat(LOOPBACK_IFACE, TYPE_TX_PACKETS);
+ }
+
+ /** {@hide} */
+ @TestApi
+ public static long getLoopbackRxPackets() {
+ return nativeGetIfaceStat(LOOPBACK_IFACE, TYPE_RX_PACKETS);
+ }
+
+ /** {@hide} */
+ @TestApi
+ public static long getLoopbackTxBytes() {
+ return nativeGetIfaceStat(LOOPBACK_IFACE, TYPE_TX_BYTES);
+ }
+
+ /** {@hide} */
+ @TestApi
+ public static long getLoopbackRxBytes() {
+ return nativeGetIfaceStat(LOOPBACK_IFACE, TYPE_RX_BYTES);
+ }
+
/**
* Return number of packets transmitted since device boot. Counts packets
* across all network interfaces, and always increases monotonically since
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 2e9eeb1..9513b9b 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -658,32 +658,40 @@
*/
public static final int PROCESS_STATE_FOREGROUND_SERVICE = 1;
/**
- * Time this uid has any process that is top while the device is sleeping, but none
- * in the "foreground service" or better state.
- */
- public static final int PROCESS_STATE_TOP_SLEEPING = 2;
- /**
* Time this uid has any process in an active foreground state, but none in the
* "top sleeping" or better state.
*/
- public static final int PROCESS_STATE_FOREGROUND = 3;
+ public static final int PROCESS_STATE_FOREGROUND = 2;
/**
* Time this uid has any process in an active background state, but none in the
* "foreground" or better state.
*/
- public static final int PROCESS_STATE_BACKGROUND = 4;
+ public static final int PROCESS_STATE_BACKGROUND = 3;
+ /**
+ * Time this uid has any process that is top while the device is sleeping, but not
+ * active for any other reason. We kind-of consider it a kind of cached process
+ * for execution restrictions.
+ */
+ public static final int PROCESS_STATE_TOP_SLEEPING = 4;
+ /**
+ * Time this uid has any process that is in the background but it has an activity
+ * marked as "can't save state". This is essentially a cached process, though the
+ * system will try much harder than normal to avoid killing it.
+ */
+ public static final int PROCESS_STATE_HEAVY_WEIGHT = 5;
/**
* Time this uid has any processes that are sitting around cached, not in one of the
* other active states.
*/
- public static final int PROCESS_STATE_CACHED = 5;
+ public static final int PROCESS_STATE_CACHED = 6;
/**
* Total number of process states we track.
*/
- public static final int NUM_PROCESS_STATE = 6;
+ public static final int NUM_PROCESS_STATE = 7;
static final String[] PROCESS_STATE_NAMES = {
- "Top", "Fg Service", "Top Sleeping", "Foreground", "Background", "Cached"
+ "Top", "Fg Service", "Foreground", "Background", "Top Sleeping", "Heavy Weight",
+ "Cached"
};
public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which);
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 2acf36f..848ab88 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1136,7 +1136,7 @@
int intervalUs) {
VMDebug.startMethodTracing(fixTracePath(tracePath), bufferSize, 0, true, intervalUs);
}
-
+
/**
* Formats name of trace log file for method tracing.
*/
@@ -1706,11 +1706,11 @@
* Retrieves information about this processes memory usages. This information is broken down by
* how much is in use by dalvik, the native heap, and everything else.
*
- * <p><b>Note:</b> this method directly retrieves memory information for the give process
+ * <p><b>Note:</b> this method directly retrieves memory information for the given process
* from low-level data available to it. It may not be able to retrieve information about
* some protected allocations, such as graphics. If you want to be sure you can see
- * all information about allocations by the process, use instead
- * {@link android.app.ActivityManager#getProcessMemoryInfo(int[])}.</p>
+ * all information about allocations by the process, use
+ * {@link android.app.ActivityManager#getProcessMemoryInfo(int[])} instead.</p>
*/
public static native void getMemoryInfo(MemoryInfo memoryInfo);
diff --git a/core/java/android/os/IIncidentManager.aidl b/core/java/android/os/IIncidentManager.aidl
index 1a76648..b67b99f 100644
--- a/core/java/android/os/IIncidentManager.aidl
+++ b/core/java/android/os/IIncidentManager.aidl
@@ -16,7 +16,6 @@
package android.os;
-import android.os.IIncidentReportCompletedListener;
import android.os.IIncidentReportStatusListener;
import android.os.IncidentReportArgs;
diff --git a/core/java/android/os/IIncidentReportCompletedListener.aidl b/core/java/android/os/IIncidentReportCompletedListener.aidl
deleted file mode 100644
index 2d66bf6..0000000
--- a/core/java/android/os/IIncidentReportCompletedListener.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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;
-
-/**
- * Listener for incident report status
- *
- * {@hide}
- */
-oneway interface IIncidentReportCompletedListener {
- /**
- * Called when there has been an incident report.
- *
- * The system service implementing this method should delete or move the file
- * after it is finished with it.
- */
- void onIncidentReport(String filename);
-}
diff --git a/core/java/android/privacy/DifferentialPrivacyConfig.java b/core/java/android/privacy/DifferentialPrivacyConfig.java
new file mode 100644
index 0000000..e14893e
--- /dev/null
+++ b/core/java/android/privacy/DifferentialPrivacyConfig.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.privacy;
+
+/**
+ * An interface for differential privacy configuration.
+ * {@link DifferentialPrivacyEncoder} will apply this configuration to do differential privacy
+ * encoding.
+ *
+ * @hide
+ */
+public interface DifferentialPrivacyConfig {
+
+ /**
+ * Returns the name of the algorithm used in differential privacy config.
+ *
+ * @return The name of the algorithm
+ */
+ String getAlgorithm();
+}
diff --git a/core/java/android/privacy/DifferentialPrivacyEncoder.java b/core/java/android/privacy/DifferentialPrivacyEncoder.java
new file mode 100644
index 0000000..9355d6a
--- /dev/null
+++ b/core/java/android/privacy/DifferentialPrivacyEncoder.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.privacy;
+
+/**
+ * An interface for differential privacy encoder.
+ * Applications can use it to convert privacy sensitive data to privacy protected report.
+ * There is no decoder implemented in Android as it is not possible decode a single report by
+ * design.
+ *
+ * <p>Each type of log should have its own encoder, otherwise it may leak
+ * some information about Permanent Randomized Response(PRR, is used to create a “noisy”
+ * answer which is memoized by the client and permanently reused in place of the real answer).
+ *
+ * <p>Some encoders may not support all encoding methods, and it will throw {@link
+ * UnsupportedOperationException} if you call unsupported encoding method.
+ *
+ * <p><b>WARNING:</b> Privacy protection works only when encoder uses a suitable DP configuration,
+ * and the configuration and algorithm that is suitable is highly dependent on the use case.
+ * If the configuration is not suitable for the use case, it may hurt privacy or utility or both.
+ *
+ * @hide
+ */
+public interface DifferentialPrivacyEncoder {
+
+ /**
+ * Apply differential privacy to encode a string.
+ *
+ * @param original An arbitrary string
+ * @return Differential privacy encoded bytes derived from the string
+ */
+ byte[] encodeString(String original);
+
+ /**
+ * Apply differential privacy to encode a boolean.
+ *
+ * @param original An arbitrary boolean.
+ * @return Differential privacy encoded bytes derived from the boolean
+ */
+ byte[] encodeBoolean(boolean original);
+
+ /**
+ * Apply differential privacy to encode sequence of bytes.
+ *
+ * @param original An arbitrary byte array.
+ * @return Differential privacy encoded bytes derived from the bytes
+ */
+ byte[] encodeBits(byte[] original);
+
+ /**
+ * Returns the configuration that this encoder is using.
+ */
+ DifferentialPrivacyConfig getConfig();
+
+ /**
+ * Return True if the output from encoder is NOT securely randomized, otherwise encoder should
+ * be secure to randomize input.
+ *
+ * <b> A non-secure encoder is intended only for testing only and must not be used to process
+ * real data.
+ * </b>
+ */
+ boolean isInsecureEncoderForTest();
+}
diff --git a/core/java/android/privacy/internal/longitudinalreporting/LongitudinalReportingConfig.java b/core/java/android/privacy/internal/longitudinalreporting/LongitudinalReportingConfig.java
new file mode 100644
index 0000000..ee910fc
--- /dev/null
+++ b/core/java/android/privacy/internal/longitudinalreporting/LongitudinalReportingConfig.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.privacy.internal.longitudinalreporting;
+
+import android.privacy.DifferentialPrivacyConfig;
+import android.privacy.internal.rappor.RapporConfig;
+import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class to store {@link LongitudinalReportingEncoder} configuration.
+ *
+ * <ul>
+ * <li> f is probability to flip input value, used in IRR.
+ * <li> p is probability to override input value, used in PRR1.
+ * <li> q is probability to set input value as 1 when result of PRR(p) is true, used in PRR2.
+ * </ul>
+ *
+ * @hide
+ */
+public class LongitudinalReportingConfig implements DifferentialPrivacyConfig {
+
+ private static final String ALGORITHM_NAME = "LongitudinalReporting";
+
+ // Probability to flip input value.
+ private final double mProbabilityF;
+
+ // Probability to override original value.
+ private final double mProbabilityP;
+ // Probability to override value with 1.
+ private final double mProbabilityQ;
+
+ // IRR config to randomize original value
+ private final RapporConfig mIRRConfig;
+
+ private final String mEncoderId;
+
+ /**
+ * Constructor to create {@link LongitudinalReportingConfig} used for {@link
+ * LongitudinalReportingEncoder}
+ *
+ * @param encoderId Unique encoder id.
+ * @param probabilityF Probability F used in Longitudinal Reporting algorithm.
+ * @param probabilityP Probability P used in Longitudinal Reporting algorithm. This will be
+ * quantized to the nearest 1/256.
+ * @param probabilityQ Probability Q used in Longitudinal Reporting algorithm. This will be
+ * quantized to the nearest 1/256.
+ */
+ public LongitudinalReportingConfig(String encoderId, double probabilityF,
+ double probabilityP, double probabilityQ) {
+ Preconditions.checkArgument(probabilityF >= 0 && probabilityF <= 1,
+ "probabilityF must be in range [0.0, 1.0]");
+ this.mProbabilityF = probabilityF;
+ Preconditions.checkArgument(probabilityP >= 0 && probabilityP <= 1,
+ "probabilityP must be in range [0.0, 1.0]");
+ this.mProbabilityP = probabilityP;
+ Preconditions.checkArgument(probabilityQ >= 0 && probabilityQ <= 1,
+ "probabilityQ must be in range [0.0, 1.0]");
+ this.mProbabilityQ = probabilityQ;
+ Preconditions.checkArgument(!TextUtils.isEmpty(encoderId), "encoderId cannot be empty");
+ mEncoderId = encoderId;
+ mIRRConfig = new RapporConfig(encoderId, 1, 0.0, probabilityF, 1 - probabilityF, 1, 1);
+ }
+
+ @Override
+ public String getAlgorithm() {
+ return ALGORITHM_NAME;
+ }
+
+ RapporConfig getIRRConfig() {
+ return mIRRConfig;
+ }
+
+ double getProbabilityP() {
+ return mProbabilityP;
+ }
+
+ double getProbabilityQ() {
+ return mProbabilityQ;
+ }
+
+ String getEncoderId() {
+ return mEncoderId;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("EncoderId: %s, ProbabilityF: %.3f, ProbabilityP: %.3f"
+ + ", ProbabilityQ: %.3f",
+ mEncoderId, mProbabilityF, mProbabilityP, mProbabilityQ);
+ }
+}
diff --git a/core/java/android/privacy/internal/longitudinalreporting/LongitudinalReportingEncoder.java b/core/java/android/privacy/internal/longitudinalreporting/LongitudinalReportingEncoder.java
new file mode 100644
index 0000000..219868d
--- /dev/null
+++ b/core/java/android/privacy/internal/longitudinalreporting/LongitudinalReportingEncoder.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.privacy.internal.longitudinalreporting;
+
+import android.privacy.DifferentialPrivacyEncoder;
+import android.privacy.internal.rappor.RapporConfig;
+import android.privacy.internal.rappor.RapporEncoder;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Differential privacy encoder by using Longitudinal Reporting algorithm.
+ *
+ * <b>
+ * Notes: It supports encodeBoolean() only for now.
+ * </b>
+ *
+ * <p>
+ * Definition:
+ * PRR = Permanent Randomized Response
+ * IRR = Instantaneous Randomized response
+ *
+ * Algorithm:
+ * Step 1: Create long-term secrets x(ignoreOriginalInput)=Ber(P), y=Ber(Q), where Ber denotes
+ * Bernoulli distribution on {0, 1}, and we use it as a long-term secret, we implement Ber(x) by
+ * using PRR(2x, 0) when x < 1/2, PRR(2(1-x), 1) when x >= 1/2.
+ * Step 2: If x is 0, report IRR(F, original), otherwise report IRR(F, y)
+ * </p>
+ *
+ * Reference: go/bit-reporting-with-longitudinal-privacy
+ * TODO: Add a public blog / site to explain how it works.
+ *
+ * @hide
+ */
+public class LongitudinalReportingEncoder implements DifferentialPrivacyEncoder {
+
+ // Suffix that will be added to Rappor's encoder id. There's a (relatively) small risk some
+ // other Rappor encoder may re-use the same encoder id.
+ private static final String PRR1_ENCODER_ID = "prr1_encoder_id";
+ private static final String PRR2_ENCODER_ID = "prr2_encoder_id";
+
+ private final LongitudinalReportingConfig mConfig;
+
+ // IRR encoder to encode input value.
+ private final RapporEncoder mIRREncoder;
+
+ // A value that used to replace original value as input, so there's always a chance we are
+ // doing IRR on a fake value not actual original value.
+ // Null if original value does not need to be replaced.
+ private final Boolean mFakeValue;
+
+ // True if encoder is securely randomized.
+ private final boolean mIsSecure;
+
+ /**
+ * Create {@link LongitudinalReportingEncoder} with
+ * {@link LongitudinalReportingConfig} provided.
+ *
+ * @param config Longitudinal Reporting parameters to encode input
+ * @param userSecret User generated secret that used to generate PRR
+ * @return {@link LongitudinalReportingEncoder} instance
+ */
+ public static LongitudinalReportingEncoder createEncoder(LongitudinalReportingConfig config,
+ byte[] userSecret) {
+ return new LongitudinalReportingEncoder(config, true, userSecret);
+ }
+
+ /**
+ * Create <strong>insecure</strong> {@link LongitudinalReportingEncoder} with
+ * {@link LongitudinalReportingConfig} provided.
+ * Should not use it to process sensitive data.
+ *
+ * @param config Rappor parameters to encode input.
+ * @return {@link LongitudinalReportingEncoder} instance.
+ */
+ @VisibleForTesting
+ public static LongitudinalReportingEncoder createInsecureEncoderForTest(
+ LongitudinalReportingConfig config) {
+ return new LongitudinalReportingEncoder(config, false, null);
+ }
+
+ private LongitudinalReportingEncoder(LongitudinalReportingConfig config,
+ boolean secureEncoder, byte[] userSecret) {
+ mConfig = config;
+ mIsSecure = secureEncoder;
+ final boolean ignoreOriginalInput = getLongTermRandomizedResult(config.getProbabilityP(),
+ secureEncoder, userSecret, config.getEncoderId() + PRR1_ENCODER_ID);
+
+ if (ignoreOriginalInput) {
+ mFakeValue = getLongTermRandomizedResult(config.getProbabilityQ(),
+ secureEncoder, userSecret, config.getEncoderId() + PRR2_ENCODER_ID);
+ } else {
+ // Not using fake value, so IRR will be processed on real input value.
+ mFakeValue = null;
+ }
+
+ final RapporConfig irrConfig = config.getIRRConfig();
+ mIRREncoder = secureEncoder
+ ? RapporEncoder.createEncoder(irrConfig, userSecret)
+ : RapporEncoder.createInsecureEncoderForTest(irrConfig);
+ }
+
+ @Override
+ public byte[] encodeString(String original) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public byte[] encodeBoolean(boolean original) {
+ if (mFakeValue != null) {
+ // Use the fake value generated in PRR.
+ original = mFakeValue.booleanValue();
+ }
+ return mIRREncoder.encodeBoolean(original);
+ }
+
+ @Override
+ public byte[] encodeBits(byte[] bits) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public LongitudinalReportingConfig getConfig() {
+ return mConfig;
+ }
+
+ @Override
+ public boolean isInsecureEncoderForTest() {
+ return !mIsSecure;
+ }
+
+ /**
+ * Get PRR result that with probability p is 1, probability 1-p is 0.
+ */
+ @VisibleForTesting
+ public static boolean getLongTermRandomizedResult(double p, boolean secureEncoder,
+ byte[] userSecret, String encoderId) {
+ // Use Rappor to get PRR result. Rappor's P and Q are set to 0 and 1 so IRR will not be
+ // effective.
+ // As Rappor has rapporF/2 chance returns 0, rapporF/2 chance returns 1, and 1-rapporF
+ // chance returns original input.
+ // If p < 0.5, setting rapporF=2p and input=0 will make Rappor has p chance to return 1
+ // P(output=1 | input=0) = rapporF/2 = 2p/2 = p.
+ // If p >= 0.5, setting rapporF=2(1-p) and input=1 will make Rappor has p chance
+ // to return 1.
+ // P(output=1 | input=1) = rapporF/2 + (1 - rapporF) = 2(1-p)/2 + (1 - 2(1-p)) = p.
+ final double effectiveF = p < 0.5f ? p * 2 : (1 - p) * 2;
+ final boolean prrInput = p < 0.5f ? false : true;
+ final RapporConfig prrConfig = new RapporConfig(encoderId, 1, effectiveF,
+ 0, 1, 1, 1);
+ final RapporEncoder encoder = secureEncoder
+ ? RapporEncoder.createEncoder(prrConfig, userSecret)
+ : RapporEncoder.createInsecureEncoderForTest(prrConfig);
+ return encoder.encodeBoolean(prrInput)[0] > 0;
+ }
+}
diff --git a/core/java/android/privacy/internal/rappor/RapporConfig.java b/core/java/android/privacy/internal/rappor/RapporConfig.java
new file mode 100644
index 0000000..221999b
--- /dev/null
+++ b/core/java/android/privacy/internal/rappor/RapporConfig.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.privacy.internal.rappor;
+
+import android.privacy.DifferentialPrivacyConfig;
+import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class to store {@link RapporEncoder} config.
+ *
+ * @hide
+ */
+public class RapporConfig implements DifferentialPrivacyConfig {
+
+ private static final String ALGORITHM_NAME = "Rappor";
+
+ final String mEncoderId;
+ final int mNumBits;
+ final double mProbabilityF;
+ final double mProbabilityP;
+ final double mProbabilityQ;
+ final int mNumCohorts;
+ final int mNumBloomHashes;
+
+ /**
+ * Constructor for {@link RapporConfig}.
+ *
+ * @param encoderId Unique id for encoder.
+ * @param numBits Number of bits to be encoded in Rappor algorithm.
+ * @param probabilityF Probability F that used in Rappor algorithm. This will be
+ * quantized to the nearest 1/128.
+ * @param probabilityP Probability P that used in Rappor algorithm.
+ * @param probabilityQ Probability Q that used in Rappor algorithm.
+ * @param numCohorts Number of cohorts that used in Rappor algorithm.
+ * @param numBloomHashes Number of bloom hashes that used in Rappor algorithm.
+ */
+ public RapporConfig(String encoderId, int numBits, double probabilityF,
+ double probabilityP, double probabilityQ, int numCohorts, int numBloomHashes) {
+ Preconditions.checkArgument(!TextUtils.isEmpty(encoderId), "encoderId cannot be empty");
+ this.mEncoderId = encoderId;
+ Preconditions.checkArgument(numBits > 0, "numBits needs to be > 0");
+ this.mNumBits = numBits;
+ Preconditions.checkArgument(probabilityF >= 0 && probabilityF <= 1,
+ "probabilityF must be in range [0.0, 1.0]");
+ this.mProbabilityF = probabilityF;
+ Preconditions.checkArgument(probabilityP >= 0 && probabilityP <= 1,
+ "probabilityP must be in range [0.0, 1.0]");
+ this.mProbabilityP = probabilityP;
+ Preconditions.checkArgument(probabilityQ >= 0 && probabilityQ <= 1,
+ "probabilityQ must be in range [0.0, 1.0]");
+ this.mProbabilityQ = probabilityQ;
+ Preconditions.checkArgument(numCohorts > 0, "numCohorts needs to be > 0");
+ this.mNumCohorts = numCohorts;
+ Preconditions.checkArgument(numBloomHashes > 0, "numBloomHashes needs to be > 0");
+ this.mNumBloomHashes = numBloomHashes;
+ }
+
+ @Override
+ public String getAlgorithm() {
+ return ALGORITHM_NAME;
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "EncoderId: %s, NumBits: %d, ProbabilityF: %.3f, ProbabilityP: %.3f"
+ + ", ProbabilityQ: %.3f, NumCohorts: %d, NumBloomHashes: %d",
+ mEncoderId, mNumBits, mProbabilityF, mProbabilityP, mProbabilityQ,
+ mNumCohorts, mNumBloomHashes);
+ }
+}
diff --git a/core/java/android/privacy/internal/rappor/RapporEncoder.java b/core/java/android/privacy/internal/rappor/RapporEncoder.java
new file mode 100644
index 0000000..2eca4c98
--- /dev/null
+++ b/core/java/android/privacy/internal/rappor/RapporEncoder.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.privacy.internal.rappor;
+
+import android.privacy.DifferentialPrivacyEncoder;
+
+import com.google.android.rappor.Encoder;
+
+import java.security.SecureRandom;
+import java.util.Random;
+
+/**
+ * Differential privacy encoder by using
+ * <a href="https://research.google.com/pubs/pub42852.html">RAPPOR</a>
+ * algorithm.
+ *
+ * @hide
+ */
+public class RapporEncoder implements DifferentialPrivacyEncoder {
+
+ // Hard-coded seed and secret for insecure encoder
+ private static final long INSECURE_RANDOM_SEED = 0x12345678L;
+ private static final byte[] INSECURE_SECRET = new byte[]{
+ (byte) 0xD7, (byte) 0x68, (byte) 0x99, (byte) 0x93,
+ (byte) 0x94, (byte) 0x13, (byte) 0x53, (byte) 0x54,
+ (byte) 0xFE, (byte) 0xD0, (byte) 0x7E, (byte) 0x54,
+ (byte) 0xFE, (byte) 0xD0, (byte) 0x7E, (byte) 0x54,
+ (byte) 0xD7, (byte) 0x68, (byte) 0x99, (byte) 0x93,
+ (byte) 0x94, (byte) 0x13, (byte) 0x53, (byte) 0x54,
+ (byte) 0xFE, (byte) 0xD0, (byte) 0x7E, (byte) 0x54,
+ (byte) 0xFE, (byte) 0xD0, (byte) 0x7E, (byte) 0x54,
+ (byte) 0xD7, (byte) 0x68, (byte) 0x99, (byte) 0x93,
+ (byte) 0x94, (byte) 0x13, (byte) 0x53, (byte) 0x54,
+ (byte) 0xFE, (byte) 0xD0, (byte) 0x7E, (byte) 0x54,
+ (byte) 0xFE, (byte) 0xD0, (byte) 0x7E, (byte) 0x54
+ };
+ private static final SecureRandom sSecureRandom = new SecureRandom();
+
+ private final RapporConfig mConfig;
+
+ // Rappor encoder
+ private final Encoder mEncoder;
+ // True if encoder is secure (seed is securely randomized)
+ private final boolean mIsSecure;
+
+
+ private RapporEncoder(RapporConfig config, boolean secureEncoder, byte[] userSecret) {
+ mConfig = config;
+ mIsSecure = secureEncoder;
+ final Random random;
+ if (secureEncoder) {
+ // Use SecureRandom as random generator.
+ random = sSecureRandom;
+ } else {
+ // Hard-coded random generator, to have deterministic result.
+ random = new Random(INSECURE_RANDOM_SEED);
+ userSecret = INSECURE_SECRET;
+ }
+ mEncoder = new Encoder(random, null, null,
+ userSecret, config.mEncoderId, config.mNumBits,
+ config.mProbabilityF, config.mProbabilityP, config.mProbabilityQ,
+ config.mNumCohorts, config.mNumBloomHashes);
+ }
+
+ /**
+ * Create {@link RapporEncoder} with {@link RapporConfig} and user secret provided.
+ *
+ * @param config Rappor parameters to encode input.
+ * @param userSecret Per device unique secret key.
+ * @return {@link RapporEncoder} instance.
+ */
+ public static RapporEncoder createEncoder(RapporConfig config, byte[] userSecret) {
+ return new RapporEncoder(config, true, userSecret);
+ }
+
+ /**
+ * Create <strong>insecure</strong> {@link RapporEncoder} with {@link RapporConfig} provided.
+ * Should not use it to process sensitive data.
+ *
+ * @param config Rappor parameters to encode input.
+ * @return {@link RapporEncoder} instance.
+ */
+ public static RapporEncoder createInsecureEncoderForTest(RapporConfig config) {
+ return new RapporEncoder(config, false, null);
+ }
+
+ @Override
+ public byte[] encodeString(String original) {
+ return mEncoder.encodeString(original);
+ }
+
+ @Override
+ public byte[] encodeBoolean(boolean original) {
+ return mEncoder.encodeBoolean(original);
+ }
+
+ @Override
+ public byte[] encodeBits(byte[] bits) {
+ return mEncoder.encodeBits(bits);
+ }
+
+ @Override
+ public RapporConfig getConfig() {
+ return mConfig;
+ }
+
+ @Override
+ public boolean isInsecureEncoderForTest() {
+ return !mIsSecure;
+ }
+}
diff --git a/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.aidl b/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.aidl
index 1058463a..1674e51 100644
--- a/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.aidl
+++ b/core/java/android/security/recoverablekeystore/KeyEntryRecoveryData.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security.keystore.recoverablekeystore;
+package android.security.recoverablekeystore;
/* @hide */
parcelable KeyEntryRecoveryData;
diff --git a/core/java/android/security/recoverablekeystore/RecoverableKeyStoreLoader.java b/core/java/android/security/recoverablekeystore/RecoverableKeyStoreLoader.java
index 0510320..f2f225d 100644
--- a/core/java/android/security/recoverablekeystore/RecoverableKeyStoreLoader.java
+++ b/core/java/android/security/recoverablekeystore/RecoverableKeyStoreLoader.java
@@ -19,37 +19,40 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
+import android.os.UserHandle;
+import android.security.KeyStore;
+import android.util.AndroidException;
import com.android.internal.widget.ILockSettings;
import java.util.List;
/**
- * A wrapper around KeyStore which lets key be exported to
- * trusted hardware on server side and recovered later.
+ * A wrapper around KeyStore which lets key be exported to trusted hardware on server side and
+ * recovered later.
*
* @hide
*/
-public class RecoverableKeyStoreLoader {
+public class RecoverableKeyStoreLoader {
- private final ILockSettings mBinder;
+ public static final String PERMISSION_RECOVER_KEYSTORE = "android.permission.RECOVER_KEYSTORE";
- // Exception codes, should be in sync with {@code KeyStoreException}.
- public static final int SYSTEM_ERROR = 4;
-
+ public static final int NO_ERROR = KeyStore.NO_ERROR;
+ public static final int SYSTEM_ERROR = KeyStore.SYSTEM_ERROR;
public static final int UNINITIALIZED_RECOVERY_PUBLIC_KEY = 20;
-
// Too many updates to recovery public key or server parameters.
public static final int RATE_LIMIT_EXCEEDED = 21;
+ private final ILockSettings mBinder;
+
private RecoverableKeyStoreLoader(ILockSettings binder) {
mBinder = binder;
}
- /**
- * @hide
- */
+ /** @hide */
public static RecoverableKeyStoreLoader getInstance() {
ILockSettings lockSettings =
ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings"));
@@ -57,29 +60,69 @@
}
/**
+ * Exceptions returned by {@link RecoverableKeyStoreLoader}.
+ *
* @hide
*/
- public static class RecoverableKeyStoreLoaderException extends Exception {
- private final int mErrorCode;
+ public static class RecoverableKeyStoreLoaderException extends AndroidException {
+ private int mErrorCode;
- public RecoverableKeyStoreLoaderException(int errorCode, String message) {
- super(message);
- mErrorCode = errorCode;
+ /**
+ * Creates new {@link #RecoverableKeyStoreLoaderException} instance from the error code.
+ *
+ * @param errorCode
+ * @hide
+ */
+ public static RecoverableKeyStoreLoaderException fromErrorCode(int errorCode) {
+ return new RecoverableKeyStoreLoaderException(
+ errorCode, getMessageFromErrorCode(errorCode));
}
+ /**
+ * Creates new {@link #RecoverableKeyStoreLoaderException} from {@link
+ * ServiceSpecificException}.
+ *
+ * @param e exception thrown on service side.
+ * @hide
+ */
+ static RecoverableKeyStoreLoaderException fromServiceSpecificException(
+ ServiceSpecificException e) throws RecoverableKeyStoreLoaderException {
+ throw RecoverableKeyStoreLoaderException.fromErrorCode(e.errorCode);
+ }
+
+ private RecoverableKeyStoreLoaderException(int errorCode, String message) {
+ super(message);
+ }
+
+ /** Returns errorCode. */
public int getErrorCode() {
return mErrorCode;
}
+
+ /** @hide */
+ private static String getMessageFromErrorCode(int errorCode) {
+ switch (errorCode) {
+ case NO_ERROR:
+ return "OK";
+ case SYSTEM_ERROR:
+ return "System error";
+ case UNINITIALIZED_RECOVERY_PUBLIC_KEY:
+ return "Recovery service is not initialized";
+ case RATE_LIMIT_EXCEEDED:
+ return "Rate limit exceeded";
+ default:
+ return String.valueOf("Unknown error code " + errorCode);
+ }
+ }
}
/**
* Initializes key recovery service for the calling application. RecoverableKeyStoreLoader
- * randomly chooses one of the keys from the list
- * and keeps it to use for future key export operations. Collection of all keys
- * in the list must be signed by the provided {@code rootCertificateAlias}, which must also be
- * present in the list of root certificates preinstalled on the device. The random selection
- * allows RecoverableKeyStoreLoader to select which of a set of remote recovery service
- * devices will be used.
+ * randomly chooses one of the keys from the list and keeps it to use for future key export
+ * operations. Collection of all keys in the list must be signed by the provided {@code
+ * rootCertificateAlias}, which must also be present in the list of root certificates
+ * preinstalled on the device. The random selection allows RecoverableKeyStoreLoader to select
+ * which of a set of remote recovery service devices will be used.
*
* <p>In addition, RecoverableKeyStoreLoader enforces a delay of three months between
* consecutive initialization attempts, to limit the ability of an attacker to often switch
@@ -88,127 +131,200 @@
* @param rootCertificateAlias alias of a root certificate preinstalled on the device
* @param signedPublicKeyList binary blob a list of X509 certificates and signature
* @throws RecoverableKeyStoreLoaderException if signature is invalid, or key rotation was rate
- * limited.
+ * limited.
* @hide
*/
- public void initRecoveryService(@NonNull String rootCertificateAlias,
- @NonNull byte[] signedPublicKeyList)
+ public void initRecoveryService(
+ @NonNull String rootCertificateAlias, @NonNull byte[] signedPublicKeyList)
throws RecoverableKeyStoreLoaderException {
- throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented");
- // TODO: extend widget/ILockSettings.aidl
- /* try {
- mBinder.initRecoveryService(rootCertificate, publicKeyList);
- } catch (RemoteException e) {
+ try {
+ mBinder.initRecoveryService(
+ rootCertificateAlias, signedPublicKeyList, UserHandle.getCallingUserId());
+ } catch (RemoteException e) {
throw e.rethrowFromSystemServer();
- } */
+ } catch (ServiceSpecificException e) {
+ throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+ }
}
/**
- * Returns data necessary to store all recoverable keys for given account.
- * Key material is encrypted with user secret and recovery public key.
+ * Returns data necessary to store all recoverable keys for given account. Key material is
+ * encrypted with user secret and recovery public key.
+ *
+ * @param account specific to Recovery agent.
+ * @return Data necessary to recover keystore.
+ * @hide
*/
public KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account)
throws RecoverableKeyStoreLoaderException {
- throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented");
+ try {
+ KeyStoreRecoveryData recoveryData =
+ mBinder.getRecoveryData(account, UserHandle.getCallingUserId());
+ return recoveryData;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (ServiceSpecificException e) {
+ throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+ }
}
/**
* Server parameters used to generate new recovery key blobs. This value will be included in
- * {@code KeyStoreRecoveryData.getEncryptedRecoveryKeyBlob()}.
- * The same value must be included in vaultParams {@link startRecoverySession}
+ * {@code KeyStoreRecoveryData.getEncryptedRecoveryKeyBlob()}. The same value must be included
+ * in vaultParams {@link startRecoverySession}
*
+ * @param serverParameters included in recovery key blob.
* @see #getRecoveryData
* @throws RecoverableKeyStoreLoaderException If parameters rotation is rate limited.
+ * @hide
*/
- public void updateServerParameters(long serverParameters)
+ public void setServerParameters(long serverParameters)
throws RecoverableKeyStoreLoaderException {
- throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented");
+ try {
+ mBinder.setServerParameters(serverParameters, UserHandle.getCallingUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (ServiceSpecificException e) {
+ throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+ }
}
/**
- * Updates recovery status for given keys.
- * It is used to notify keystore that key was successfully stored on the server or
- * there were an error. Returned as a part of KeyInfo data structure.
+ * Updates recovery status for given keys. It is used to notify keystore that key was
+ * successfully stored on the server or there were an error. Returned as a part of KeyInfo data
+ * structure.
*
* @param packageName Application whose recoverable keys' statuses are to be updated.
* @param aliases List of application-specific key aliases. If the array is empty, updates the
- * status for all existing recoverable keys.
+ * status for all existing recoverable keys.
* @param status Status specific to recovery agent.
*/
- public void setRecoveryStatus(@NonNull String packageName, @Nullable String[] aliases,
- int status) throws NameNotFoundException, RecoverableKeyStoreLoaderException {
- throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented");
+ public void setRecoveryStatus(
+ @NonNull String packageName, @Nullable String[] aliases, int status)
+ throws NameNotFoundException, RecoverableKeyStoreLoaderException {
+ try {
+ mBinder.setRecoveryStatus(packageName, aliases, status, UserHandle.getCallingUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (ServiceSpecificException e) {
+ throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+ }
}
/**
- * Specifies a set of secret types used for end-to-end keystore encryption.
- * Knowing all of them is necessary to recover data.
+ * Specifies a set of secret types used for end-to-end keystore encryption. Knowing all of them
+ * is necessary to recover data.
*
- * @param secretTypes {@link KeyStoreRecoveryMetadata#TYPE_LOCKSCREEN} or
- * {@link KeyStoreRecoveryMetadata#TYPE_CUSTOM_PASSWORD}
+ * @param secretTypes {@link KeyStoreRecoveryMetadata#TYPE_LOCKSCREEN} or {@link
+ * KeyStoreRecoveryMetadata#TYPE_CUSTOM_PASSWORD}
*/
- public void setRecoverySecretTypes(@NonNull @KeyStoreRecoveryMetadata.UserSecretType
- int[] secretTypes) throws RecoverableKeyStoreLoaderException {
- throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented");
+ public void setRecoverySecretTypes(
+ @NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] secretTypes)
+ throws RecoverableKeyStoreLoaderException {
+ try {
+ mBinder.setRecoverySecretTypes(secretTypes, UserHandle.getCallingUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (ServiceSpecificException e) {
+ throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+ }
}
/**
- * Defines a set of secret types used for end-to-end keystore encryption.
- * Knowing all of them is necessary to generate KeyStoreRecoveryData.
+ * Defines a set of secret types used for end-to-end keystore encryption. Knowing all of them is
+ * necessary to generate KeyStoreRecoveryData.
+ *
+ * @return list of recovery secret types
* @see KeyStoreRecoveryData
*/
public @NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] getRecoverySecretTypes()
throws RecoverableKeyStoreLoaderException {
- throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented");
+ try {
+ return mBinder.getRecoverySecretTypes(UserHandle.getCallingUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (ServiceSpecificException e) {
+ throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+ }
}
/**
* Returns a list of recovery secret types, necessary to create a pending recovery snapshot.
- * When user enters a secret of a pending type
- * {@link #recoverySecretAvailable} should be called.
+ * When user enters a secret of a pending type {@link #recoverySecretAvailable} should be
+ * called.
+ *
+ * @return list of recovery secret types
*/
public @NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] getPendingRecoverySecretTypes()
throws RecoverableKeyStoreLoaderException {
- throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented");
+ try {
+ return mBinder.getPendingRecoverySecretTypes(UserHandle.getCallingUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (ServiceSpecificException e) {
+ throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+ }
}
/**
- * Method notifies KeyStore that a user-generated secret is available.
- * This method generates a symmetric session key which a trusted remote device can use
- * to return a recovery key.
- * Caller should use {@link KeyStoreRecoveryMetadata#clearSecret} to override the secret value
- * in memory.
+ * Method notifies KeyStore that a user-generated secret is available. This method generates a
+ * symmetric session key which a trusted remote device can use to return a recovery key. Caller
+ * should use {@link KeyStoreRecoveryMetadata#clearSecret} to override the secret value in
+ * memory.
*
- * @param recoverySecret user generated secret together with parameters necessary to
- * regenerate it on a new device.
+ * @param recoverySecret user generated secret together with parameters necessary to regenerate
+ * it on a new device.
*/
public void recoverySecretAvailable(@NonNull KeyStoreRecoveryMetadata recoverySecret)
throws RecoverableKeyStoreLoaderException {
- throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented");
+ try {
+ mBinder.recoverySecretAvailable(recoverySecret, UserHandle.getCallingUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (ServiceSpecificException e) {
+ throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+ }
}
/**
* Initializes recovery session and returns a blob with proof of recovery secrets possession.
- * The method generates symmetric key for a session, which trusted remote device can use
- * to return recovery key.
+ * The method generates symmetric key for a session, which trusted remote device can use to
+ * return recovery key.
*
* @param sessionId ID for recovery session.
- * @param verifierPublicKey Certificate with Public key used to create the recovery blob on
- * the source device. Keystore will verify the certificate using root of trust.
+ * @param verifierPublicKey Certificate with Public key used to create the recovery blob on the
+ * source device. Keystore will verify the certificate using root of trust.
* @param vaultParams Must match the parameters in the corresponding field in the recovery blob.
- * Used to limit number of guesses.
+ * Used to limit number of guesses.
* @param vaultChallenge Data passed from server for this recovery session and used to prevent
- * replay attacks
+ * replay attacks
* @param secrets Secrets provided by user, the method only uses type and secret fields.
- * @return Binary blob with recovery claim. It is encrypted with verifierPublicKey and
- * contains a proof of user secrets, session symmetric key and parameters necessary to identify
- * the counter with the number of failed recovery attempts.
+ * @return Binary blob with recovery claim. It is encrypted with verifierPublicKey and contains
+ * a proof of user secrets, session symmetric key and parameters necessary to identify the
+ * counter with the number of failed recovery attempts.
*/
- public @NonNull byte[] startRecoverySession(@NonNull String sessionId,
- @NonNull byte[] verifierPublicKey, @NonNull byte[] vaultParams,
- @NonNull byte[] vaultChallenge, @NonNull List<KeyStoreRecoveryMetadata> secrets)
+ public @NonNull byte[] startRecoverySession(
+ @NonNull String sessionId,
+ @NonNull byte[] verifierPublicKey,
+ @NonNull byte[] vaultParams,
+ @NonNull byte[] vaultChallenge,
+ @NonNull List<KeyStoreRecoveryMetadata> secrets)
throws RecoverableKeyStoreLoaderException {
- throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented");
+ try {
+ byte[] recoveryClaim =
+ mBinder.startRecoverySession(
+ sessionId,
+ verifierPublicKey,
+ vaultParams,
+ vaultChallenge,
+ secrets,
+ UserHandle.getCallingUserId());
+ return recoveryClaim;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (ServiceSpecificException e) {
+ throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+ }
}
/**
@@ -217,12 +333,21 @@
* @param sessionId Id for recovery session, same as in = {@link startRecoverySession}.
* @param recoveryKeyBlob Recovery blob encrypted by symmetric key generated for this session.
* @param applicationKeys Application keys. Key material can be decrypted using recoveryKeyBlob
- * and session. KeyStore only uses package names from the application info in
- * {@link KeyEntryRecoveryData}. Caller is responsibility to perform certificates check.
+ * and session. KeyStore only uses package names from the application info in {@link
+ * KeyEntryRecoveryData}. Caller is responsibility to perform certificates check.
*/
- public void recoverKeys(@NonNull String sessionId, @NonNull byte[] recoveryKeyBlob,
+ public void recoverKeys(
+ @NonNull String sessionId,
+ @NonNull byte[] recoveryKeyBlob,
@NonNull List<KeyEntryRecoveryData> applicationKeys)
throws RecoverableKeyStoreLoaderException {
- throw new RecoverableKeyStoreLoaderException(SYSTEM_ERROR, "Not implemented");
+ try {
+ mBinder.recoverKeys(
+ sessionId, recoveryKeyBlob, applicationKeys, UserHandle.getCallingUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (ServiceSpecificException e) {
+ throw RecoverableKeyStoreLoaderException.fromServiceSpecificException(e);
+ }
}
}
diff --git a/core/java/android/service/autofill/FieldClassification.java b/core/java/android/service/autofill/FieldClassification.java
index 001e3a0..001b291 100644
--- a/core/java/android/service/autofill/FieldClassification.java
+++ b/core/java/android/service/autofill/FieldClassification.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.os.Parcel;
-import android.os.Parcelable;
import android.view.autofill.Helper;
import com.android.internal.util.Preconditions;
@@ -34,8 +33,7 @@
* Represents the <a href="AutofillService.html#FieldClassification">field classification</a>
* results for a given field.
*/
-// TODO(b/70291841): let caller handle Parcelable...
-public final class FieldClassification implements Parcelable {
+public final class FieldClassification {
private final ArrayList<Match> mMatches;
@@ -72,42 +70,38 @@
return "FieldClassification: " + mMatches;
}
- /////////////////////////////////////
- // Parcelable "contract" methods. //
- /////////////////////////////////////
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel parcel, int flags) {
+ private void writeToParcel(Parcel parcel) {
parcel.writeInt(mMatches.size());
for (int i = 0; i < mMatches.size(); i++) {
mMatches.get(i).writeToParcel(parcel);
}
}
- public static final Parcelable.Creator<FieldClassification> CREATOR =
- new Parcelable.Creator<FieldClassification>() {
-
- @Override
- public FieldClassification createFromParcel(Parcel parcel) {
- final int size = parcel.readInt();
- final ArrayList<Match> matches = new ArrayList<>();
- for (int i = 0; i < size; i++) {
- matches.add(i, Match.readFromParcel(parcel));
- }
-
- return new FieldClassification(matches);
+ private static FieldClassification readFromParcel(Parcel parcel) {
+ final int size = parcel.readInt();
+ final ArrayList<Match> matches = new ArrayList<>();
+ for (int i = 0; i < size; i++) {
+ matches.add(i, Match.readFromParcel(parcel));
}
- @Override
- public FieldClassification[] newArray(int size) {
- return new FieldClassification[size];
+ return new FieldClassification(matches);
+ }
+
+ static FieldClassification[] readArrayFromParcel(Parcel parcel) {
+ final int length = parcel.readInt();
+ final FieldClassification[] fcs = new FieldClassification[length];
+ for (int i = 0; i < length; i++) {
+ fcs[i] = readFromParcel(parcel);
}
- };
+ return fcs;
+ }
+
+ static void writeArrayToParcel(@NonNull Parcel parcel, @NonNull FieldClassification[] fcs) {
+ parcel.writeInt(fcs.length);
+ for (int i = 0; i < fcs.length; i++) {
+ fcs[i].writeToParcel(parcel);
+ }
+ }
/**
* Represents the score of a {@link UserData} entry for the field.
@@ -170,23 +164,5 @@
private static Match readFromParcel(@NonNull Parcel parcel) {
return new Match(parcel.readString(), parcel.readFloat());
}
-
- /** @hide */
- public static Match[] readArrayFromParcel(@NonNull Parcel parcel) {
- final int length = parcel.readInt();
- final Match[] matches = new Match[length];
- for (int i = 0; i < length; i++) {
- matches[i] = readFromParcel(parcel);
- }
- return matches;
- }
-
- /** @hide */
- public static void writeArrayToParcel(@NonNull Parcel parcel, @NonNull Match[] matches) {
- parcel.writeInt(matches.length);
- for (int i = 0; i < matches.length; i++) {
- matches[i].writeToParcel(parcel);
- }
- }
}
}
diff --git a/core/java/android/service/autofill/FillEventHistory.java b/core/java/android/service/autofill/FillEventHistory.java
index 2eb44cf..df62446 100644
--- a/core/java/android/service/autofill/FillEventHistory.java
+++ b/core/java/android/service/autofill/FillEventHistory.java
@@ -156,7 +156,8 @@
final AutofillId[] detectedFields = event.mDetectedFieldIds;
parcel.writeParcelableArray(detectedFields, flags);
if (detectedFields != null) {
- parcel.writeParcelableArray(event.mDetectedFieldClassifications, flags);
+ FieldClassification.writeArrayToParcel(parcel,
+ event.mDetectedFieldClassifications);
}
}
}
@@ -551,7 +552,7 @@
AutofillId.class);
final FieldClassification[] detectedFieldClassifications =
(detectedFieldIds != null)
- ? parcel.readParcelableArray(null, FieldClassification.class)
+ ? FieldClassification.readArrayFromParcel(parcel)
: null;
selection.addEvent(new Event(eventType, datasetId, clientState,
diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
index fb6f637..b8f2191 100644
--- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
@@ -27,6 +27,7 @@
void setDesiredSize(int width, int height);
void setDisplayPadding(in Rect padding);
void setVisibility(boolean visible);
+ void setInAmbientMode(boolean inAmbientDisplay);
void dispatchPointer(in MotionEvent event);
void dispatchWallpaperCommand(String action, int x, int y,
int z, in Bundle extras);
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index e5ab3e1..595bfb7 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -102,6 +102,7 @@
private static final int DO_DETACH = 20;
private static final int DO_SET_DESIRED_SIZE = 30;
private static final int DO_SET_DISPLAY_PADDING = 40;
+ private static final int DO_IN_AMBIENT_MODE = 50;
private static final int MSG_UPDATE_SURFACE = 10000;
private static final int MSG_VISIBILITY_CHANGED = 10010;
@@ -195,6 +196,7 @@
float mPendingYOffsetStep;
boolean mPendingSync;
MotionEvent mPendingMove;
+ boolean mIsInAmbientMode;
// Needed for throttling onComputeColors.
private long mLastColorInvalidation;
@@ -431,6 +433,15 @@
public boolean isPreview() {
return mIWallpaperEngine.mIsPreview;
}
+
+ /**
+ * Returns true if this engine is running in ambient mode -- that is,
+ * it is being shown in low power mode, in always on display.
+ * @hide
+ */
+ public boolean isInAmbientMode() {
+ return mIsInAmbientMode;
+ }
/**
* Control whether this wallpaper will receive raw touch events
@@ -549,6 +560,15 @@
}
/**
+ * Called when the device enters or exits ambient mode.
+ *
+ * @param inAmbientMode {@code true} if in ambient mode.
+ * @hide
+ */
+ public void onAmbientModeChanged(boolean inAmbientMode) {
+ }
+
+ /**
* Called when an application has changed the desired virtual size of
* the wallpaper.
*/
@@ -631,6 +651,16 @@
return null;
}
+ /**
+ * Sets internal engine state. Only for testing.
+ * @param created {@code true} or {@code false}.
+ * @hide
+ */
+ @VisibleForTesting
+ public void setCreated(boolean created) {
+ mCreated = created;
+ }
+
protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
out.print(prefix); out.print("mInitializing="); out.print(mInitializing);
out.print(" mDestroyed="); out.println(mDestroyed);
@@ -683,7 +713,8 @@
}
Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
mCaller.sendMessage(msg);
- } else {event.recycle();
+ } else {
+ event.recycle();
}
}
@@ -986,6 +1017,26 @@
updateSurface(false, false, false);
}
+ /**
+ * Executes life cycle event and updates internal ambient mode state based on
+ * message sent from handler.
+ *
+ * @param inAmbientMode True if in ambient mode.
+ * @hide
+ */
+ @VisibleForTesting
+ public void doAmbientModeChanged(boolean inAmbientMode) {
+ if (!mDestroyed) {
+ if (DEBUG) {
+ Log.v(TAG, "onAmbientModeChanged(" + inAmbientMode + "): " + this);
+ }
+ mIsInAmbientMode = inAmbientMode;
+ if (mCreated) {
+ onAmbientModeChanged(inAmbientMode);
+ }
+ }
+ }
+
void doDesiredSizeChanged(int desiredWidth, int desiredHeight) {
if (!mDestroyed) {
if (DEBUG) Log.v(TAG, "onDesiredSizeChanged("
@@ -1226,6 +1277,12 @@
mCaller.sendMessage(msg);
}
+ @Override
+ public void setInAmbientMode(boolean inAmbientDisplay) throws RemoteException {
+ Message msg = mCaller.obtainMessageI(DO_IN_AMBIENT_MODE, inAmbientDisplay ? 1 : 0);
+ mCaller.sendMessage(msg);
+ }
+
public void dispatchPointer(MotionEvent event) {
if (mEngine != null) {
mEngine.dispatchPointer(event);
@@ -1263,6 +1320,7 @@
mCaller.sendMessage(msg);
}
+ @Override
public void executeMessage(Message message) {
switch (message.what) {
case DO_ATTACH: {
@@ -1289,6 +1347,11 @@
}
case DO_SET_DISPLAY_PADDING: {
mEngine.doDisplayPaddingChanged((Rect) message.obj);
+ return;
+ }
+ case DO_IN_AMBIENT_MODE: {
+ mEngine.doAmbientModeChanged(message.arg1 != 0);
+ return;
}
case MSG_UPDATE_SURFACE:
mEngine.updateSurface(true, false, false);
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index fba358c..71e039a 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -492,7 +492,9 @@
}
}
- private void reflow(CharSequence s, int where, int before, int after) {
+ /** @hide */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public void reflow(CharSequence s, int where, int before, int after) {
if (s != mBase)
return;
@@ -805,8 +807,8 @@
return;
}
- int firstBlock = -1;
- int lastBlock = -1;
+ /*final*/ int firstBlock = -1;
+ /*final*/ int lastBlock = -1;
for (int i = 0; i < mNumberOfBlocks; i++) {
if (mBlockEndLines[i] >= startLine) {
firstBlock = i;
@@ -821,10 +823,10 @@
}
final int lastBlockEndLine = mBlockEndLines[lastBlock];
- boolean createBlockBefore = startLine > (firstBlock == 0 ? 0 :
+ final boolean createBlockBefore = startLine > (firstBlock == 0 ? 0 :
mBlockEndLines[firstBlock - 1] + 1);
- boolean createBlock = newLineCount > 0;
- boolean createBlockAfter = endLine < mBlockEndLines[lastBlock];
+ final boolean createBlock = newLineCount > 0;
+ final boolean createBlockAfter = endLine < mBlockEndLines[lastBlock];
int numAddedBlocks = 0;
if (createBlockBefore) numAddedBlocks++;
@@ -863,12 +865,18 @@
if (numAddedBlocks + numRemovedBlocks != 0 && mBlocksAlwaysNeedToBeRedrawn != null) {
final ArraySet<Integer> set = new ArraySet<>();
+ final int changedBlockCount = numAddedBlocks - numRemovedBlocks;
for (int i = 0; i < mBlocksAlwaysNeedToBeRedrawn.size(); i++) {
Integer block = mBlocksAlwaysNeedToBeRedrawn.valueAt(i);
- if (block > firstBlock) {
- block += numAddedBlocks - numRemovedBlocks;
+ if (block < firstBlock) {
+ // block index is before firstBlock add it since it did not change
+ set.add(block);
}
- set.add(block);
+ if (block > lastBlock) {
+ // block index is after lastBlock, the index reduced to += changedBlockCount
+ block += changedBlockCount;
+ set.add(block);
+ }
}
mBlocksAlwaysNeedToBeRedrawn = set;
}
diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java
index 73a9478..75c1000 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -65,18 +65,14 @@
* v2 stripping rollback protection, or verify integrity of the APK.
*
* @throws PackageParserException if the APK's signature failed to verify.
- * @throws SignatureNotFoundException if a signature corresponding to minLevel or greater
- * is not found, except in the case of no JAR signature.
*/
public static Result verify(String apkPath, int minSignatureSchemeVersion, boolean systemDir)
- throws PackageParserException, SignatureNotFoundException {
- boolean verified = false;
- Certificate[][] signerCerts;
- int level = VERSION_APK_SIGNATURE_SCHEME_V2;
+ throws PackageParserException {
// first try v2
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "verifyV2");
try {
+ Certificate[][] signerCerts;
signerCerts = ApkSignatureSchemeV2Verifier.verify(apkPath);
Signature[] signerSigs = convertToSignatures(signerCerts);
@@ -93,12 +89,12 @@
} finally {
closeQuietly(jarFile);
}
- return new Result(signerCerts, signerSigs);
+ return new Result(signerCerts, signerSigs, VERSION_APK_SIGNATURE_SCHEME_V2);
} catch (SignatureNotFoundException e) {
// not signed with v2, try older if allowed
if (minSignatureSchemeVersion >= VERSION_APK_SIGNATURE_SCHEME_V2) {
- throw new SignatureNotFoundException(
- "No APK Signature Scheme v2 signature found for " + apkPath, e);
+ throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
+ "No APK Signature Scheme v2 signature in package " + apkPath, e);
}
} catch (PackageParserException e) {
// preserve any new exceptions explicitly thrown here
@@ -178,7 +174,7 @@
}
}
}
- return new Result(lastCerts, lastSigs);
+ return new Result(lastCerts, lastSigs, VERSION_JAR_SIGNATURE_SCHEME);
} catch (GeneralSecurityException e) {
throw new PackageParserException(INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING,
"Failed to collect certificates from " + apkPath, e);
@@ -254,10 +250,12 @@
public static class Result {
public final Certificate[][] certs;
public final Signature[] sigs;
+ public final int signatureSchemeVersion;
- public Result(Certificate[][] certs, Signature[] sigs) {
+ public Result(Certificate[][] certs, Signature[] sigs, int signingVersion) {
this.certs = certs;
this.sigs = sigs;
+ this.signatureSchemeVersion = signingVersion;
}
}
}
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index fdc9f92..ed60430 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -16,17 +16,23 @@
package android.view.textclassifier;
+import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
import android.annotation.WorkerThread;
import android.os.LocaleList;
+import android.util.ArraySet;
import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
/**
* Interface for providing text classification related features.
@@ -58,6 +64,20 @@
})
@interface EntityType {}
+ /** Designates that the TextClassifier should identify all entity types it can. **/
+ int ENTITY_PRESET_ALL = 0;
+ /** Designates that the TextClassifier should identify no entities. **/
+ int ENTITY_PRESET_NONE = 1;
+ /** Designates that the TextClassifier should identify a base set of entities determined by the
+ * TextClassifier. **/
+ int ENTITY_PRESET_BASE = 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "ENTITY_CONFIG_" },
+ value = {ENTITY_PRESET_ALL, ENTITY_PRESET_NONE, ENTITY_PRESET_BASE})
+ @interface EntityPreset {}
+
/**
* No-op TextClassifier.
* This may be used to turn off TextClassifier features.
@@ -217,6 +237,8 @@
* Returns a {@link TextLinks} that may be applied to the text to annotate it with links
* information.
*
+ * If no options are supplied, default values will be used, determined by the TextClassifier.
+ *
* @param text the text to generate annotations for
* @param options configuration for link generation
*
@@ -251,6 +273,16 @@
}
/**
+ * Returns a {@link Collection} of the entity types in the specified preset.
+ *
+ * @see #ENTITIES_ALL
+ * @see #ENTITIES_NONE
+ */
+ default Collection<String> getEntitiesForPreset(@EntityPreset int entityPreset) {
+ return Collections.EMPTY_LIST;
+ }
+
+ /**
* Logs a TextClassifier event.
*
* @param source the text classifier used to generate this event
@@ -268,6 +300,62 @@
return TextClassifierConstants.DEFAULT;
}
+ /**
+ * Configuration object for specifying what entities to identify.
+ *
+ * Configs are initially based on a predefined preset, and can be modified from there.
+ */
+ final class EntityConfig {
+ private final @TextClassifier.EntityPreset int mEntityPreset;
+ private final Collection<String> mExcludedEntityTypes;
+ private final Collection<String> mIncludedEntityTypes;
+
+ public EntityConfig(@TextClassifier.EntityPreset int mEntityPreset) {
+ this.mEntityPreset = mEntityPreset;
+ mExcludedEntityTypes = new ArraySet<>();
+ mIncludedEntityTypes = new ArraySet<>();
+ }
+
+ /**
+ * Specifies an entity to include in addition to any specified by the enity preset.
+ *
+ * Note that if an entity has been excluded, the exclusion will take precedence.
+ */
+ public EntityConfig includeEntities(String... entities) {
+ for (String entity : entities) {
+ mIncludedEntityTypes.add(entity);
+ }
+ return this;
+ }
+
+ /**
+ * Specifies an entity to be excluded.
+ */
+ public EntityConfig excludeEntities(String... entities) {
+ for (String entity : entities) {
+ mExcludedEntityTypes.add(entity);
+ }
+ return this;
+ }
+
+ /**
+ * Returns an unmodifiable list of the final set of entities to find.
+ */
+ public List<String> getEntities(TextClassifier textClassifier) {
+ ArrayList<String> entities = new ArrayList<>();
+ for (String entity : textClassifier.getEntitiesForPreset(mEntityPreset)) {
+ if (!mExcludedEntityTypes.contains(entity)) {
+ entities.add(entity);
+ }
+ }
+ for (String entity : mIncludedEntityTypes) {
+ if (!mExcludedEntityTypes.contains(entity) && !entities.contains(entity)) {
+ entities.add(entity);
+ }
+ }
+ return Collections.unmodifiableList(entities);
+ }
+ }
/**
* Utility functions for TextClassifier methods.
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index d7aaee7..aea3cb0 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -42,6 +42,9 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -66,6 +69,18 @@
private static final String MODEL_FILE_REGEX = "textclassifier\\.smartselection\\.(.*)\\.model";
private static final String UPDATED_MODEL_FILE_PATH =
"/data/misc/textclassifier/textclassifier.smartselection.model";
+ private static final List<String> ENTITY_TYPES_ALL =
+ Collections.unmodifiableList(Arrays.asList(
+ TextClassifier.TYPE_ADDRESS,
+ TextClassifier.TYPE_EMAIL,
+ TextClassifier.TYPE_PHONE,
+ TextClassifier.TYPE_URL));
+ private static final List<String> ENTITY_TYPES_BASE =
+ Collections.unmodifiableList(Arrays.asList(
+ TextClassifier.TYPE_ADDRESS,
+ TextClassifier.TYPE_EMAIL,
+ TextClassifier.TYPE_PHONE,
+ TextClassifier.TYPE_URL));
private final Context mContext;
@@ -168,17 +183,23 @@
@Override
public TextLinks generateLinks(
- @NonNull CharSequence text, @NonNull TextLinks.Options options) {
+ @NonNull CharSequence text, @Nullable TextLinks.Options options) {
Utils.validateInput(text);
final String textString = text.toString();
final TextLinks.Builder builder = new TextLinks.Builder(textString);
try {
- LocaleList defaultLocales = options != null ? options.getDefaultLocales() : null;
+ final LocaleList defaultLocales = options != null ? options.getDefaultLocales() : null;
+ final Collection<String> entitiesToIdentify =
+ options != null && options.getEntityConfig() != null
+ ? options.getEntityConfig().getEntities(this) : ENTITY_TYPES_ALL;
final SmartSelection smartSelection = getSmartSelection(defaultLocales);
final SmartSelection.AnnotatedSpan[] annotations = smartSelection.annotate(textString);
for (SmartSelection.AnnotatedSpan span : annotations) {
- final Map<String, Float> entityScores = new HashMap<>();
final SmartSelection.ClassificationResult[] results = span.getClassification();
+ if (results.length == 0 || !entitiesToIdentify.contains(results[0].mCollection)) {
+ continue;
+ }
+ final Map<String, Float> entityScores = new HashMap<>();
for (int i = 0; i < results.length; i++) {
entityScores.put(results[i].mCollection, results[i].mScore);
}
@@ -193,6 +214,20 @@
}
@Override
+ public Collection<String> getEntitiesForPreset(@TextClassifier.EntityPreset int entityPreset) {
+ switch (entityPreset) {
+ case TextClassifier.ENTITY_PRESET_NONE:
+ return Collections.emptyList();
+ case TextClassifier.ENTITY_PRESET_BASE:
+ return ENTITY_TYPES_BASE;
+ case TextClassifier.ENTITY_PRESET_ALL:
+ // fall through
+ default:
+ return ENTITY_TYPES_ALL;
+ }
+ }
+
+ @Override
public void logEvent(String source, String event) {
if (LOG_TAG.equals(source)) {
mMetricsLogger.count(event, 1);
diff --git a/core/java/android/view/textclassifier/TextLinks.java b/core/java/android/view/textclassifier/TextLinks.java
index 4fe5662..6c587cf 100644
--- a/core/java/android/view/textclassifier/TextLinks.java
+++ b/core/java/android/view/textclassifier/TextLinks.java
@@ -161,11 +161,12 @@
public static final class Options {
private LocaleList mDefaultLocales;
+ private TextClassifier.EntityConfig mEntityConfig;
/**
- * @param defaultLocales ordered list of locale preferences that may be used to disambiguate
- * the provided text. If no locale preferences exist, set this to null or an empty
- * locale list.
+ * @param defaultLocales ordered list of locale preferences that may be used to
+ * disambiguate the provided text. If no locale preferences exist,
+ * set this to null or an empty locale list.
*/
public Options setDefaultLocales(@Nullable LocaleList defaultLocales) {
mDefaultLocales = defaultLocales;
@@ -173,6 +174,17 @@
}
/**
+ * Sets the entity configuration to use. This determines what types of entities the
+ * TextClassifier will look for.
+ *
+ * @param entityConfig EntityConfig to use
+ */
+ public Options setEntityConfig(@Nullable TextClassifier.EntityConfig entityConfig) {
+ mEntityConfig = entityConfig;
+ return this;
+ }
+
+ /**
* @return ordered list of locale preferences that can be used to disambiguate
* the provided text.
*/
@@ -180,6 +192,15 @@
public LocaleList getDefaultLocales() {
return mDefaultLocales;
}
+
+ /**
+ * @return The config representing the set of entities to look for.
+ * @see #setEntityConfig(TextClassifier.EntityConfig)
+ */
+ @Nullable
+ public TextClassifier.EntityConfig getEntityConfig() {
+ return mEntityConfig;
+ }
}
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index e985923..de5a822 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2081,6 +2081,48 @@
}
/**
+ * Define the directory used to store WebView data for the current process.
+ * The provided suffix will be used when constructing data and cache
+ * directory paths. If this API is not called, no suffix will be used.
+ * Each directory can be used by only one process in the application. If more
+ * than one process in an app wishes to use WebView, only one process can use
+ * the default directory, and other processes must call this API to define
+ * a unique suffix.
+ * <p>
+ * This API must be called before any instances of WebView are created in
+ * this process and before any other methods in the android.webkit package
+ * are called by this process.
+ *
+ * @param suffix The directory name suffix to be used for the current
+ * process. Must not contain a path separator.
+ * @throws IllegalStateException if WebView has already been initialized
+ * in the current process.
+ * @throws IllegalArgumentException if the suffix contains a path separator.
+ */
+ public static void setDataDirectorySuffix(String suffix) {
+ WebViewFactory.setDataDirectorySuffix(suffix);
+ }
+
+ /**
+ * Indicate that the current process does not intend to use WebView, and
+ * that an exception should be thrown if a WebView is created or any other
+ * methods in the android.webkit package are used.
+ * <p>
+ * Applications with multiple processes may wish to call this in processes
+ * which are not intended to use WebView to prevent potential data directory
+ * conflicts (see {@link #setDataDirectorySuffix}) and to avoid accidentally
+ * incurring the memory usage of initializing WebView in long-lived
+ * processes which have no need for it.
+ *
+ * @throws IllegalStateException if WebView has already been initialized
+ * in the current process.
+ */
+ public static void disableWebView() {
+ WebViewFactory.disableWebView();
+ }
+
+
+ /**
* @deprecated This was used for Gears, which has been deprecated.
* @hide
*/
diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java
index 7339931..f067091 100644
--- a/core/java/android/webkit/WebViewDelegate.java
+++ b/core/java/android/webkit/WebViewDelegate.java
@@ -218,4 +218,11 @@
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Returns the data directory suffix to use, or null for none.
+ */
+ public String getDataDirectorySuffix() {
+ return WebViewFactory.getDataDirectorySuffix();
+ }
}
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 9db0e8d..e3efad0 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -33,6 +33,7 @@
import android.util.ArraySet;
import android.util.Log;
+import java.io.File;
import java.lang.reflect.Method;
/**
@@ -63,6 +64,8 @@
private static final Object sProviderLock = new Object();
private static PackageInfo sPackageInfo;
private static Boolean sWebViewSupported;
+ private static boolean sWebViewDisabled;
+ private static String sDataDirectorySuffix; // stored here so it can be set without loading WV
// Error codes for loadWebViewNativeLibraryFromPackage
public static final int LIBLOAD_SUCCESS = 0;
@@ -115,6 +118,45 @@
/**
* @hide
*/
+ static void disableWebView() {
+ synchronized (sProviderLock) {
+ if (sProviderInstance != null) {
+ throw new IllegalStateException(
+ "Can't disable WebView: WebView already initialized");
+ }
+ sWebViewDisabled = true;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ static void setDataDirectorySuffix(String suffix) {
+ synchronized (sProviderLock) {
+ if (sProviderInstance != null) {
+ throw new IllegalStateException(
+ "Can't set data directory suffix: WebView already initialized");
+ }
+ if (suffix.indexOf(File.separatorChar) >= 0) {
+ throw new IllegalArgumentException("Suffix " + suffix
+ + " contains a path separator");
+ }
+ sDataDirectorySuffix = suffix;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ static String getDataDirectorySuffix() {
+ synchronized (sProviderLock) {
+ return sDataDirectorySuffix;
+ }
+ }
+
+ /**
+ * @hide
+ */
public static String getWebViewLibrary(ApplicationInfo ai) {
if (ai.metaData != null)
return ai.metaData.getString("com.android.webview.WebViewLibrary");
@@ -204,6 +246,11 @@
throw new UnsupportedOperationException();
}
+ if (sWebViewDisabled) {
+ throw new IllegalStateException(
+ "WebView.disableWebView() was called: WebView is disabled");
+ }
+
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getProvider()");
try {
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java
index 6fb02b1..efc9c02 100644
--- a/core/java/com/android/internal/app/procstats/ProcessState.java
+++ b/core/java/com/android/internal/app/procstats/ProcessState.java
@@ -91,14 +91,14 @@
STATE_TOP, // ActivityManager.PROCESS_STATE_TOP
STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
- STATE_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
STATE_IMPORTANT_BACKGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
STATE_IMPORTANT_BACKGROUND, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
STATE_BACKUP, // ActivityManager.PROCESS_STATE_BACKUP
- STATE_HEAVY_WEIGHT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
STATE_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE
STATE_RECEIVER, // ActivityManager.PROCESS_STATE_RECEIVER
+ STATE_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
+ STATE_HEAVY_WEIGHT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
STATE_HOME, // ActivityManager.PROCESS_STATE_HOME
STATE_LAST_ACTIVITY, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
STATE_CACHED_ACTIVITY, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java
index 2ce7936..96ba2b0 100644
--- a/core/java/com/android/internal/app/procstats/ProcessStats.java
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.java
@@ -81,10 +81,10 @@
public static final int STATE_IMPORTANT_FOREGROUND = 2;
public static final int STATE_IMPORTANT_BACKGROUND = 3;
public static final int STATE_BACKUP = 4;
- public static final int STATE_HEAVY_WEIGHT = 5;
- public static final int STATE_SERVICE = 6;
- public static final int STATE_SERVICE_RESTARTING = 7;
- public static final int STATE_RECEIVER = 8;
+ public static final int STATE_SERVICE = 5;
+ public static final int STATE_SERVICE_RESTARTING = 6;
+ public static final int STATE_RECEIVER = 7;
+ public static final int STATE_HEAVY_WEIGHT = 8;
public static final int STATE_HOME = 9;
public static final int STATE_LAST_ACTIVITY = 10;
public static final int STATE_CACHED_ACTIVITY = 11;
@@ -141,8 +141,8 @@
public static final int[] NON_CACHED_PROC_STATES = new int[] {
STATE_PERSISTENT, STATE_TOP, STATE_IMPORTANT_FOREGROUND,
- STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, STATE_HEAVY_WEIGHT,
- STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER
+ STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
+ STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER, STATE_HEAVY_WEIGHT
};
public static final int[] BACKGROUND_PROC_STATES = new int[] {
@@ -152,13 +152,13 @@
public static final int[] ALL_PROC_STATES = new int[] { STATE_PERSISTENT,
STATE_TOP, STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
- STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER,
- STATE_HOME, STATE_LAST_ACTIVITY, STATE_CACHED_ACTIVITY,
+ STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER,
+ STATE_HEAVY_WEIGHT, STATE_HOME, STATE_LAST_ACTIVITY, STATE_CACHED_ACTIVITY,
STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY
};
// Current version of the parcel format.
- private static final int PARCEL_VERSION = 22;
+ private static final int PARCEL_VERSION = 23;
// In-memory Parcel magic number, used to detect attempts to unmarshall bad data
private static final int MAGIC = 0x50535454;
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index d49d572..a075705 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -236,6 +236,7 @@
moveInMediaStore(visibleFileBefore, getFileForDocId(afterDocId, true));
if (!TextUtils.equals(docId, afterDocId)) {
+ scanFile(after);
return afterDocId;
} else {
return null;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index bef247f..6510a70 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -120,7 +120,7 @@
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 170 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 171 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS;
@@ -8678,13 +8678,15 @@
} else if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
// Persistent and other foreground states go here.
uidRunningState = PROCESS_STATE_FOREGROUND_SERVICE;
- } else if (procState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
- uidRunningState = PROCESS_STATE_TOP_SLEEPING;
} else if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
// Persistent and other foreground states go here.
uidRunningState = PROCESS_STATE_FOREGROUND;
} else if (procState <= ActivityManager.PROCESS_STATE_RECEIVER) {
uidRunningState = PROCESS_STATE_BACKGROUND;
+ } else if (procState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
+ uidRunningState = PROCESS_STATE_TOP_SLEEPING;
+ } else if (procState <= ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
+ uidRunningState = PROCESS_STATE_HEAVY_WEIGHT;
} else {
uidRunningState = PROCESS_STATE_CACHED;
}
diff --git a/core/java/com/android/internal/os/ByteTransferPipe.java b/core/java/com/android/internal/os/ByteTransferPipe.java
new file mode 100644
index 0000000..6489894
--- /dev/null
+++ b/core/java/com/android/internal/os/ByteTransferPipe.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Helper class to get byte data through a pipe from a client app. Also {@see TransferPipe}.
+ */
+public class ByteTransferPipe extends TransferPipe {
+ static final String TAG = "ByteTransferPipe";
+
+ private ByteArrayOutputStream mOutputStream;
+
+ public ByteTransferPipe() throws IOException {
+ super();
+ }
+
+ public ByteTransferPipe(String bufferPrefix) throws IOException {
+ super(bufferPrefix, "ByteTransferPipe");
+ }
+
+ @Override
+ protected OutputStream getNewOutputStream() {
+ mOutputStream = new ByteArrayOutputStream();
+ return mOutputStream;
+ }
+
+ public byte[] get() throws IOException {
+ go(null);
+ return mOutputStream.toByteArray();
+ }
+}
diff --git a/core/java/com/android/internal/os/TransferPipe.java b/core/java/com/android/internal/os/TransferPipe.java
index 738ecc0b..1c09bd6 100644
--- a/core/java/com/android/internal/os/TransferPipe.java
+++ b/core/java/com/android/internal/os/TransferPipe.java
@@ -34,11 +34,12 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
/**
* Helper for transferring data through a pipe from a client app.
*/
-public final class TransferPipe implements Runnable, Closeable {
+public class TransferPipe implements Runnable, Closeable {
static final String TAG = "TransferPipe";
static final boolean DEBUG = false;
@@ -64,7 +65,11 @@
}
public TransferPipe(String bufferPrefix) throws IOException {
- mThread = new Thread(this, "TransferPipe");
+ this(bufferPrefix, "TransferPipe");
+ }
+
+ protected TransferPipe(String bufferPrefix, String threadName) throws IOException {
+ mThread = new Thread(this, threadName);
mFds = ParcelFileDescriptor.createPipe();
mBufferPrefix = bufferPrefix;
}
@@ -234,11 +239,15 @@
}
}
+ protected OutputStream getNewOutputStream() {
+ return new FileOutputStream(mOutFd);
+ }
+
@Override
public void run() {
final byte[] buffer = new byte[1024];
final FileInputStream fis;
- final FileOutputStream fos;
+ final OutputStream fos;
synchronized (this) {
ParcelFileDescriptor readFd = getReadFd();
@@ -247,7 +256,7 @@
return;
}
fis = new FileInputStream(readFd.getFileDescriptor());
- fos = new FileOutputStream(mOutFd);
+ fos = getNewOutputStream();
}
if (DEBUG) Slog.i(TAG, "Ready to read pipe...");
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index 8f80bfe..0d2b29b 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -50,6 +50,7 @@
private TextView mShortcutView;
private ImageView mSubMenuArrowView;
private ImageView mGroupDivider;
+ private LinearLayout mContent;
private Drawable mBackground;
private int mTextAppearance;
@@ -114,6 +115,8 @@
mSubMenuArrowView.setImageDrawable(mSubMenuArrow);
}
mGroupDivider = findViewById(com.android.internal.R.id.group_divider);
+
+ mContent = findViewById(com.android.internal.R.id.content);
}
public void initialize(MenuItemImpl itemData, int menuType) {
@@ -131,6 +134,18 @@
setContentDescription(itemData.getContentDescription());
}
+ private void addContentView(View v) {
+ addContentView(v, -1);
+ }
+
+ private void addContentView(View v, int index) {
+ if (mContent != null) {
+ mContent.addView(v, index);
+ } else {
+ addView(v, index);
+ }
+ }
+
public void setForceShowIcon(boolean forceShow) {
mPreserveIconSpacing = mForceShowIcon = forceShow;
}
@@ -270,7 +285,7 @@
LayoutInflater inflater = getInflater();
mIconView = (ImageView) inflater.inflate(com.android.internal.R.layout.list_menu_item_icon,
this, false);
- addView(mIconView, 0);
+ addContentView(mIconView, 0);
}
private void insertRadioButton() {
@@ -278,7 +293,7 @@
mRadioButton =
(RadioButton) inflater.inflate(com.android.internal.R.layout.list_menu_item_radio,
this, false);
- addView(mRadioButton);
+ addContentView(mRadioButton);
}
private void insertCheckBox() {
@@ -286,7 +301,7 @@
mCheckBox =
(CheckBox) inflater.inflate(com.android.internal.R.layout.list_menu_item_checkbox,
this, false);
- addView(mCheckBox);
+ addContentView(mCheckBox);
}
public boolean prefersCondensedTitle() {
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index ee16ab6..164a745 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -17,6 +17,10 @@
package com.android.internal.widget;
import android.app.trust.IStrongAuthTracker;
+import android.os.Bundle;
+import android.security.recoverablekeystore.KeyEntryRecoveryData;
+import android.security.recoverablekeystore.KeyStoreRecoveryData;
+import android.security.recoverablekeystore.KeyStoreRecoveryMetadata;
import com.android.internal.widget.ICheckCredentialProgressCallback;
import com.android.internal.widget.VerifyCredentialResponse;
@@ -52,4 +56,22 @@
boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
in byte[] token, int requestedQuality, int userId);
void unlockUserWithToken(long tokenHandle, in byte[] token, int userId);
+
+ // RecoverableKeyStoreLoader methods.
+ // {@code ServiceSpecificException} may be thrown to signal an error, which caller can
+ // convert to {@code RecoverableKeyStoreLoader}.
+ void initRecoveryService(in String rootCertificateAlias, in byte[] signedPublicKeyList,
+ int userId);
+ KeyStoreRecoveryData getRecoveryData(in byte[] account, int userId);
+ void setServerParameters(long serverParameters, int userId);
+ void setRecoveryStatus(in String packageName, in String[] aliases, int status, int userId);
+ void setRecoverySecretTypes(in int[] secretTypes, int userId);
+ int[] getRecoverySecretTypes(int userId);
+ int[] getPendingRecoverySecretTypes(int userId);
+ void recoverySecretAvailable(in KeyStoreRecoveryMetadata recoverySecret, int userId);
+ byte[] startRecoverySession(in String sessionId,
+ in byte[] verifierPublicKey, in byte[] vaultParams, in byte[] vaultChallenge,
+ in List<KeyStoreRecoveryMetadata> secrets, int userId);
+ void recoverKeys(in String sessionId, in byte[] recoveryKeyBlob,
+ in List<KeyEntryRecoveryData> applicationKeys, int userId);
}
diff --git a/core/proto/android/internal/processstats.proto b/core/proto/android/internal/processstats.proto
new file mode 100644
index 0000000..5629c2d
--- /dev/null
+++ b/core/proto/android/internal/processstats.proto
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 com.android.internal.app.procstats;
+
+message ProcessStatsProto {
+ enum MemoryFactor {
+ MEM_FACTOR_NORMAL = 0;
+ MEM_FACTOR_MODERATE = 1;
+ MEM_FACTOR_LOW = 2;
+ MEM_FACTOR_CRITICAL = 3;
+ }
+}
diff --git a/core/proto/android/os/cpuinfo.proto b/core/proto/android/os/cpuinfo.proto
index a95fa57..522ff24 100644
--- a/core/proto/android/os/cpuinfo.proto
+++ b/core/proto/android/os/cpuinfo.proto
@@ -18,8 +18,6 @@
option java_multiple_files = true;
option java_outer_classname = "CpuInfoProto";
-import "frameworks/base/tools/streaming_proto/stream.proto";
-
package android.os;
/**
@@ -31,8 +29,6 @@
message CpuInfo {
message TaskStats {
- option (stream_proto.stream_msg).enable_fields_mapping = true;
-
optional int32 total = 1; // total number of cpu tasks
optional int32 running = 2; // number of running tasks
optional int32 sleeping = 3; // number of sleeping tasks
@@ -42,8 +38,6 @@
optional TaskStats task_stats = 1;
message MemStats { // unit in kB
- option (stream_proto.stream_msg).enable_fields_mapping = true;
-
optional int32 total = 1;
optional int32 used = 2;
optional int32 free = 3;
@@ -54,8 +48,6 @@
optional MemStats swap = 3;
message CpuUsage { // unit is percentage %
- option (stream_proto.stream_msg).enable_fields_mapping = true;
-
optional int32 cpu = 1; // 400% cpu indicates 4 cores
optional int32 user = 2;
optional int32 nice = 3;
@@ -70,8 +62,6 @@
// Next Tag: 13
message Task {
- option (stream_proto.stream_msg).enable_fields_mapping = true;
-
optional int32 pid = 1;
optional int32 tid = 2;
optional string user = 3;
@@ -80,8 +70,6 @@
optional float cpu = 6; // precentage of cpu usage of the task
enum Status {
- option (stream_proto.stream_enum).enable_enums_mapping = true;
-
STATUS_UNKNOWN = 0;
STATUS_D = 1; // uninterruptible sleep
STATUS_R = 2; // running
@@ -95,8 +83,6 @@
// How Android memory manager will treat the task
enum Policy {
- option (stream_proto.stream_enum).enable_enums_mapping = true;
-
POLICY_UNKNOWN = 0;
POLICY_fg = 1; // foreground, the name is lower case for parsing the value
POLICY_bg = 2; // background, the name is lower case for parsing the value
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 4015a7e..ac8f26d 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -28,13 +28,14 @@
import "frameworks/base/core/proto/android/providers/settings.proto";
import "frameworks/base/core/proto/android/server/activitymanagerservice.proto";
import "frameworks/base/core/proto/android/server/alarmmanagerservice.proto";
-import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
import "frameworks/base/core/proto/android/server/fingerprint.proto";
import "frameworks/base/core/proto/android/server/powermanagerservice.proto";
+import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
import "frameworks/base/core/proto/android/service/appwidget.proto";
import "frameworks/base/core/proto/android/service/battery.proto";
import "frameworks/base/core/proto/android/service/batterystats.proto";
import "frameworks/base/core/proto/android/service/diskstats.proto";
+import "frameworks/base/core/proto/android/service/graphicsstats.proto";
import "frameworks/base/core/proto/android/service/netstats.proto";
import "frameworks/base/core/proto/android/service/notification.proto";
import "frameworks/base/core/proto/android/service/package.proto";
@@ -176,6 +177,11 @@
optional com.android.server.am.proto.MemInfoProto meminfo = 3018 [
(section).type = SECTION_DUMPSYS,
- (section).args = "meminfo --proto"
+ (section).args = "meminfo -a --proto"
+ ];
+
+ optional android.service.GraphicsStatsServiceDumpProto graphicsstats = 3019 [
+ (section).type = SECTION_DUMPSYS,
+ (section).args = "graphicsstats --proto"
];
}
diff --git a/core/proto/android/os/kernelwake.proto b/core/proto/android/os/kernelwake.proto
index eaad37a..7e5be9d 100644
--- a/core/proto/android/os/kernelwake.proto
+++ b/core/proto/android/os/kernelwake.proto
@@ -18,8 +18,6 @@
option java_multiple_files = true;
option java_outer_classname = "WakeupSourcesProto";
-import "frameworks/base/tools/streaming_proto/stream.proto";
-
package android.os;
message KernelWakeSources {
@@ -29,8 +27,6 @@
// Next Tag: 11
message WakeupSourceProto {
- option (stream_proto.stream_msg).enable_fields_mapping = true;
-
// Name of the event which triggers application processor
optional string name = 1;
diff --git a/core/proto/android/os/pagetypeinfo.proto b/core/proto/android/os/pagetypeinfo.proto
index b86ee01..f82ea76 100644
--- a/core/proto/android/os/pagetypeinfo.proto
+++ b/core/proto/android/os/pagetypeinfo.proto
@@ -18,8 +18,6 @@
option java_multiple_files = true;
option java_outer_classname = "PageTypeInfoProto";
-import "frameworks/base/tools/streaming_proto/stream.proto";
-
package android.os;
/*
@@ -63,7 +61,6 @@
// Next tag: 9
message BlockProto {
- option (stream_proto.stream_msg).enable_fields_mapping = true;
optional int32 node = 1;
diff --git a/core/proto/android/os/procrank.proto b/core/proto/android/os/procrank.proto
index f684c84..204a5af 100644
--- a/core/proto/android/os/procrank.proto
+++ b/core/proto/android/os/procrank.proto
@@ -19,7 +19,6 @@
option java_outer_classname = "ProcrankProto";
import "frameworks/base/libs/incident/proto/android/privacy.proto";
-import "frameworks/base/tools/streaming_proto/stream.proto";
package android.os;
@@ -36,7 +35,6 @@
// Next Tag: 11
message ProcessProto {
- option (stream_proto.stream_msg).enable_fields_mapping = true;
option (android.msg_privacy).dest = DEST_AUTOMATIC;
// ID of the process
diff --git a/core/proto/android/os/system_properties.proto b/core/proto/android/os/system_properties.proto
index 76a108b..a51253f 100644
--- a/core/proto/android/os/system_properties.proto
+++ b/core/proto/android/os/system_properties.proto
@@ -19,14 +19,12 @@
option java_multiple_files = true;
import "frameworks/base/libs/incident/proto/android/privacy.proto";
-import "frameworks/base/tools/streaming_proto/stream.proto";
package android.os;
// Android Platform Exported System Properties
// TODO: This is not the completed list, new properties need to be whitelisted.
message SystemPropertiesProto {
- option (stream_proto.stream_msg).enable_fields_mapping_recursively = true;
// Properties that are not specified below would be appended here.
// These values stay on device only.
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index 3af6f51..d3ca496 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -21,6 +21,7 @@
import "frameworks/base/core/proto/android/app/notification.proto";
import "frameworks/base/core/proto/android/content/intent.proto";
import "frameworks/base/core/proto/android/graphics/rect.proto";
+import "frameworks/base/core/proto/android/internal/processstats.proto";
import "frameworks/base/core/proto/android/os/looper.proto";
import "frameworks/base/core/proto/android/server/intentresolver.proto";
import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
@@ -163,7 +164,7 @@
optional int64 uptime_duration_ms = 1;
optional int64 elapsed_realtime_ms = 2;
- message NativeProcess {
+ message ProcessMemory {
optional int32 pid = 1;
optional string process_name = 2;
@@ -197,7 +198,7 @@
optional HeapInfo native_heap = 3;
optional HeapInfo dalvik_heap = 4;
repeated MemoryInfo other_heaps = 5;
- optional HeapInfo unknown_heap = 6;
+ optional MemoryInfo unknown_heap = 6;
// Summation of native_heap, dalvik_heap, and other_heaps.
optional HeapInfo total_heap = 7;
@@ -219,7 +220,113 @@
}
optional AppSummary app_summary = 9;
}
- repeated NativeProcess native_processes = 3;
+ repeated ProcessMemory native_processes = 3;
+
+ message AppData {
+ optional ProcessMemory process_memory = 1;
+
+ message ObjectStats {
+ optional int32 view_instance_count = 1;
+ optional int32 view_root_instance_count = 2;
+ optional int32 app_context_instance_count = 3;
+ optional int32 activity_instance_count = 4;
+ optional int32 global_asset_count = 5;
+ optional int32 global_asset_manager_count = 6;
+ optional int32 local_binder_object_count = 7;
+ optional int32 proxy_binder_object_count = 8;
+ optional int64 parcel_memory_kb = 9;
+ optional int32 parcel_count = 10;
+ optional int32 binder_object_death_count = 11;
+ optional int32 open_ssl_socket_count = 12;
+ optional int32 webview_instance_count = 13;
+ }
+ optional ObjectStats objects = 2;
+
+ message SqlStats {
+ optional int32 memory_used_kb = 1;
+ optional int32 pagecache_overflow_kb = 2;
+ optional int32 malloc_size_kb = 3;
+
+ message Database {
+ optional string name = 1;
+ optional int32 page_size = 2;
+ optional int32 db_size = 3;
+ // Number of lookaside slots:
+ // http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html
+ optional int32 lookaside_b = 4;
+ // Statement cache stats: hits/misses/cachesize
+ optional string cache = 5;
+ }
+ repeated Database databases = 4;
+ }
+ optional SqlStats sql = 3;
+
+ optional string asset_allocations = 4;
+ optional string unreachable_memory = 5;
+ }
+ repeated AppData app_processes = 4;
+
+ message MemItem {
+ optional string tag = 1;
+ optional string label = 2;
+ optional int32 id = 3;
+ optional bool is_proc = 4;
+ optional bool has_activities = 5;
+ optional int64 pss_kb = 6;
+ optional int64 swap_pss_kb = 7;
+ repeated MemItem sub_items = 8;
+ }
+ repeated MemItem total_pss_by_process = 5;
+ repeated MemItem total_pss_by_oom_adjustment = 6;
+ repeated MemItem total_pss_by_category = 7;
+
+ optional int64 total_ram_kb = 8;
+ optional .com.android.internal.app.procstats.ProcessStatsProto.MemoryFactor status = 9;
+ // Total free RAM = cached_pss_kb + cached_kernel_kb + free_kb.
+ optional int64 cached_pss_kb = 10;
+ optional int64 cached_kernel_kb = 11;
+ optional int64 free_kb = 12;
+ // Total used RAM = used_pss_kb + used_kernel_kb.
+ optional int64 used_pss_kb = 13;
+ optional int64 used_kernel_kb = 14;
+
+ optional int64 lost_ram_kb = 15;
+
+ optional int64 total_zram_kb = 16;
+ optional int64 zram_physical_used_in_swap_kb = 17;
+ optional int64 total_zram_swap_kb = 18;
+
+ optional int64 ksm_sharing_kb = 19;
+ optional int64 ksm_shared_kb = 20;
+ optional int64 ksm_unshared_kb = 21;
+ optional int64 ksm_volatile_kb = 22;
+
+ // The approximate per-application memory class of the current device. This
+ // gives developers an idea of how hard a memory limit you should impose on
+ // their application to let the overall system work best. The value is in
+ // megabytes; the baseline Android memory class is 16 (which happens to be the
+ // Java heap limit of those devices); some devices with more memory may have
+ // 24 or even higher numbers.
+ optional int32 tuning_mb = 23;
+ // The approximate per-application memory class of the current device when an
+ // application is running with a large heap. This is the space available for
+ // memory-intensive applications; most applications should not need this
+ // amount of memory, and should instead stay with the tuning_mb limit. The
+ // value is in megabytes. This may be the same size as tuning_mb on memory
+ // constrained devices, or it may be significantly larger on devices with a
+ // large amount of available RAM.
+ // This is the size of the application's Dalvik heap if it has specified
+ // 'android:largeHeap="true"' in its manifest.
+ optional int32 tuning_large_mb = 24;
+
+ optional int64 oom_kb = 25;
+
+ // The maximum pss size in kb that we consider a process acceptable to restore
+ // from its cached state for running in the background when RAM is low.
+ optional int64 restore_limit_kb = 26;
+
+ optional bool is_low_ram_device = 27;
+ optional bool is_high_end_gfx = 28;
}
message StickyBroadcastProto {
diff --git a/core/proto/android/service/graphicsstats.proto b/core/proto/android/service/graphicsstats.proto
index 801411d..f422065 100644
--- a/core/proto/android/service/graphicsstats.proto
+++ b/core/proto/android/service/graphicsstats.proto
@@ -19,7 +19,6 @@
option java_multiple_files = true;
option java_outer_classname = "GraphicsStatsServiceProto";
-option optimize_for = LITE_RUNTIME;
message GraphicsStatsServiceDumpProto {
repeated GraphicsStatsProto stats = 1;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 15e439e..13fedfe 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1620,6 +1620,11 @@
<permission android:name="android.permission.ACCESS_PDB_STATE"
android:protectionLevel="signature" />
+ <!-- Allows testing if a passwords is forbidden by the admins.
+ @hide <p>Not for use by third-party applications. -->
+ <permission android:name="android.permission.TEST_BLACKLISTED_PASSWORD"
+ android:protectionLevel="signature" />
+
<!-- @hide Allows system update service to notify device owner about pending updates.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.NOTIFY_PENDING_SYSTEM_UPDATE"
diff --git a/core/res/res/layout/popup_menu_item_layout.xml b/core/res/res/layout/popup_menu_item_layout.xml
index 3eecb36..3b89f0d 100644
--- a/core/res/res/layout/popup_menu_item_layout.xml
+++ b/core/res/res/layout/popup_menu_item_layout.xml
@@ -33,6 +33,7 @@
<!-- The title and summary have some gap between them,
and this 'group' should be centered vertically. -->
<LinearLayout
+ android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="?attr/dropdownListPreferredItemHeight"
android:paddingEnd="16dip"
diff --git a/core/res/res/values-af/required_apps_managed_device.xml b/core/res/res/values-af/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-af/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-af/required_apps_managed_profile.xml b/core/res/res/values-af/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-af/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-af/required_apps_managed_user.xml b/core/res/res/values-af/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-af/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-am/required_apps_managed_device.xml b/core/res/res/values-am/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-am/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-am/required_apps_managed_profile.xml b/core/res/res/values-am/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-am/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-am/required_apps_managed_user.xml b/core/res/res/values-am/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-am/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ar/required_apps_managed_device.xml b/core/res/res/values-ar/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-ar/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ar/required_apps_managed_profile.xml b/core/res/res/values-ar/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-ar/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ar/required_apps_managed_user.xml b/core/res/res/values-ar/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-ar/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index c9611e4..2f69bd5 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -66,15 +66,15 @@
<string name="PwdMmi" msgid="7043715687905254199">"تغيير كلمة المرور"</string>
<string name="PinMmi" msgid="3113117780361190304">"تغيير رمز PIN"</string>
<string name="CnipMmi" msgid="3110534680557857162">"رقم الاتصال موجود"</string>
- <string name="CnirMmi" msgid="3062102121430548731">"رقم الاتصال مقيّد"</string>
+ <string name="CnirMmi" msgid="3062102121430548731">"رقم الاتصال محظور"</string>
<string name="ThreeWCMmi" msgid="9051047170321190368">"اتصال ثلاثي"</string>
<string name="RuacMmi" msgid="7827887459138308886">"رفض المكالمات المزعجة غير المرغوب فيها"</string>
<string name="CndMmi" msgid="3116446237081575808">"تسليم رقم الاتصال"</string>
<string name="DndMmi" msgid="1265478932418334331">"عدم الإزعاج"</string>
- <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"الإعداد الافتراضي لمعرف المتصل هو مقيّد. الاتصال التالي: مقيّد"</string>
- <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"الإعداد الافتراضي لمعرف المتصل هو مقيّد. الاتصال التالي: غير مقيّد"</string>
- <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"الإعداد الافتراضي لمعرف المتصل هو غير مقيّد. الاتصال التالي: مقيّد"</string>
- <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"الإعداد الافتراضي لمعرف المتصل هو غير مقيّد. الاتصال التالي: غير مقيّد"</string>
+ <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"الإعداد الافتراضي لمعرف المتصل هو محظور . الاتصال التالي: محظور"</string>
+ <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"الإعداد الافتراضي لمعرف المتصل هو محظور . الاتصال التالي: غير محظور"</string>
+ <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"الإعداد الافتراضي لمعرف المتصل هو غير محظور . الاتصال التالي: محظور"</string>
+ <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"الإعداد الافتراضي لمعرف المتصل هو غير محظور . الاتصال التالي: غير محظور"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"الخدمة غير متوفرة."</string>
<string name="CLIRPermanent" msgid="3377371145926835671">"لا يمكنك تغيير إعداد معرّف المتصل."</string>
<string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ليست هناك خدمة بيانات"</string>
diff --git a/core/res/res/values-b+sr+Latn/required_apps_managed_device.xml b/core/res/res/values-b+sr+Latn/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-b+sr+Latn/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-b+sr+Latn/required_apps_managed_profile.xml b/core/res/res/values-b+sr+Latn/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-b+sr+Latn/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-b+sr+Latn/required_apps_managed_user.xml b/core/res/res/values-b+sr+Latn/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-b+sr+Latn/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-be/required_apps_managed_device.xml b/core/res/res/values-be/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-be/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-be/required_apps_managed_profile.xml b/core/res/res/values-be/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-be/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-be/required_apps_managed_user.xml b/core/res/res/values-be/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-be/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-bg/required_apps_managed_device.xml b/core/res/res/values-bg/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-bg/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-bg/required_apps_managed_profile.xml b/core/res/res/values-bg/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-bg/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-bg/required_apps_managed_user.xml b/core/res/res/values-bg/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-bg/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-bn/required_apps_managed_device.xml b/core/res/res/values-bn/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-bn/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-bn/required_apps_managed_profile.xml b/core/res/res/values-bn/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-bn/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-bn/required_apps_managed_user.xml b/core/res/res/values-bn/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-bn/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 073fa12..fa3c9b1d 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1695,11 +1695,9 @@
<string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD অনুরোধটিকে ডায়াল অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
<string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD অনুরোধটিকে SS অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
<string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD অনুরোধটিকে নতুন USSD অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
- <!-- no translation found for stk_cc_ussd_to_dial_video (585340552561515305) -->
- <skip />
+ <string name="stk_cc_ussd_to_dial_video" msgid="585340552561515305">"USSD অনুরোধটিকে ভিডিও DIAL অনুরোধে পরিবর্তন করা হয়েছে।"</string>
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS অনুরোধটিকে ডায়াল অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
- <!-- no translation found for stk_cc_ss_to_dial_video (4306210904450719045) -->
- <skip />
+ <string name="stk_cc_ss_to_dial_video" msgid="4306210904450719045">"SS অনুরোধটিকে ভিডিও DIAL অনুরোধে পরিবর্তন করা হয়েছে।"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS অনুরোধটিকে নতুন USSD অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS অনুরোধটিকে নতুন SS অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"কর্মস্থলের প্রোফাইল"</string>
diff --git a/core/res/res/values-ca/required_apps_managed_device.xml b/core/res/res/values-ca/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-ca/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ca/required_apps_managed_profile.xml b/core/res/res/values-ca/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-ca/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ca/required_apps_managed_user.xml b/core/res/res/values-ca/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-ca/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-cs/required_apps_managed_device.xml b/core/res/res/values-cs/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-cs/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-cs/required_apps_managed_profile.xml b/core/res/res/values-cs/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-cs/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-cs/required_apps_managed_user.xml b/core/res/res/values-cs/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-cs/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-da/required_apps_managed_device.xml b/core/res/res/values-da/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-da/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-da/required_apps_managed_profile.xml b/core/res/res/values-da/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-da/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-da/required_apps_managed_user.xml b/core/res/res/values-da/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-da/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-de/required_apps_managed_device.xml b/core/res/res/values-de/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-de/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-de/required_apps_managed_profile.xml b/core/res/res/values-de/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-de/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-de/required_apps_managed_user.xml b/core/res/res/values-de/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-de/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-el/required_apps_managed_device.xml b/core/res/res/values-el/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-el/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-el/required_apps_managed_profile.xml b/core/res/res/values-el/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-el/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-el/required_apps_managed_user.xml b/core/res/res/values-el/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-el/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-es-rUS/required_apps_managed_device.xml b/core/res/res/values-es-rUS/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-es-rUS/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-es-rUS/required_apps_managed_profile.xml b/core/res/res/values-es-rUS/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-es-rUS/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-es-rUS/required_apps_managed_user.xml b/core/res/res/values-es-rUS/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-es-rUS/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-et/required_apps_managed_device.xml b/core/res/res/values-et/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-et/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-et/required_apps_managed_profile.xml b/core/res/res/values-et/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-et/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-et/required_apps_managed_user.xml b/core/res/res/values-et/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-et/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-eu/required_apps_managed_device.xml b/core/res/res/values-eu/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-eu/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-eu/required_apps_managed_profile.xml b/core/res/res/values-eu/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-eu/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-eu/required_apps_managed_user.xml b/core/res/res/values-eu/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-eu/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-fa/required_apps_managed_device.xml b/core/res/res/values-fa/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-fa/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-fa/required_apps_managed_profile.xml b/core/res/res/values-fa/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-fa/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-fa/required_apps_managed_user.xml b/core/res/res/values-fa/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-fa/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-fi/required_apps_managed_device.xml b/core/res/res/values-fi/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-fi/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-fi/required_apps_managed_profile.xml b/core/res/res/values-fi/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-fi/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-fi/required_apps_managed_user.xml b/core/res/res/values-fi/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-fi/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-fr-rCA/required_apps_managed_device.xml b/core/res/res/values-fr-rCA/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-fr-rCA/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-fr-rCA/required_apps_managed_profile.xml b/core/res/res/values-fr-rCA/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-fr-rCA/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-fr-rCA/required_apps_managed_user.xml b/core/res/res/values-fr-rCA/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-fr-rCA/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-gl/required_apps_managed_device.xml b/core/res/res/values-gl/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-gl/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-gl/required_apps_managed_profile.xml b/core/res/res/values-gl/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-gl/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-gl/required_apps_managed_user.xml b/core/res/res/values-gl/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-gl/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index b5aab39..b4e3904 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -977,7 +977,7 @@
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Selección de texto"</string>
<string name="addToDictionary" msgid="4352161534510057874">"Engadir ao dicionario"</string>
<string name="deleteText" msgid="6979668428458199034">"Eliminar"</string>
- <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
+ <string name="inputMethod" msgid="1653630062304567879">"Método de introdución de texto"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Accións de texto"</string>
<string name="email" msgid="4560673117055050403">"Correo electrónico"</string>
<string name="dial" msgid="1253998302767701559">"Chamar"</string>
@@ -1288,7 +1288,7 @@
<string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permiso solicitado\npara a conta <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
<string name="forward_intent_to_owner" msgid="1207197447013960896">"Estás usando esta aplicación fóra do teu perfil de traballo"</string>
<string name="forward_intent_to_work" msgid="621480743856004612">"Estás usando esta aplicación no teu perfil de traballo"</string>
- <string name="input_method_binding_label" msgid="1283557179944992649">"Método de entrada"</string>
+ <string name="input_method_binding_label" msgid="1283557179944992649">"Método de introdución de texto"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"Sincronizar"</string>
<string name="accessibility_binding_label" msgid="4148120742096474641">"Accesibilidade"</string>
<string name="wallpaper_binding_label" msgid="1240087844304687662">"Fondo de pantalla"</string>
diff --git a/core/res/res/values-gu/required_apps_managed_device.xml b/core/res/res/values-gu/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-gu/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-gu/required_apps_managed_profile.xml b/core/res/res/values-gu/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-gu/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-gu/required_apps_managed_user.xml b/core/res/res/values-gu/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-gu/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index cff1a85..eada633 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1695,11 +1695,9 @@
<string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD વિનંતીને DIAL વિનંતી પર સંશોધિત કરી."</string>
<string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD વિનંતીને SS વિનંતી પર સંશોધિત કરી."</string>
<string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD વિનંતીને નવી USSD વિનંતી પર સંશોધિત કરી."</string>
- <!-- no translation found for stk_cc_ussd_to_dial_video (585340552561515305) -->
- <skip />
+ <string name="stk_cc_ussd_to_dial_video" msgid="585340552561515305">"USSD વિનંતીને વીડિઓ DIAL વિનંતીમાં સંશોધિત કરી."</string>
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS વિનંતીને DIAL વિનંતી પર સંશોધિત કરી."</string>
- <!-- no translation found for stk_cc_ss_to_dial_video (4306210904450719045) -->
- <skip />
+ <string name="stk_cc_ss_to_dial_video" msgid="4306210904450719045">"SS વિનંતીને વીડિઓ DIAL વિનંતીમાં સંશોધિત કરી."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS વિનંતીને USSD વિનંતી પર સંશોધિત કરી."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS વિનંતીને નવી SS વિનંતી પર સંશોધિત કરી."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"કાર્યાલયની પ્રોફાઇલ"</string>
diff --git a/core/res/res/values-hi/required_apps_managed_device.xml b/core/res/res/values-hi/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-hi/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-hi/required_apps_managed_profile.xml b/core/res/res/values-hi/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-hi/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-hi/required_apps_managed_user.xml b/core/res/res/values-hi/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-hi/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-hr/required_apps_managed_device.xml b/core/res/res/values-hr/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-hr/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-hr/required_apps_managed_profile.xml b/core/res/res/values-hr/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-hr/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-hr/required_apps_managed_user.xml b/core/res/res/values-hr/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-hr/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-hu/required_apps_managed_device.xml b/core/res/res/values-hu/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-hu/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-hu/required_apps_managed_profile.xml b/core/res/res/values-hu/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-hu/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-hu/required_apps_managed_user.xml b/core/res/res/values-hu/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-hu/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-hy/required_apps_managed_device.xml b/core/res/res/values-hy/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-hy/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-hy/required_apps_managed_profile.xml b/core/res/res/values-hy/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-hy/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-hy/required_apps_managed_user.xml b/core/res/res/values-hy/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-hy/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-is/required_apps_managed_device.xml b/core/res/res/values-is/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-is/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-is/required_apps_managed_profile.xml b/core/res/res/values-is/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-is/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-is/required_apps_managed_user.xml b/core/res/res/values-is/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-is/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-iw/required_apps_managed_device.xml b/core/res/res/values-iw/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-iw/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-iw/required_apps_managed_profile.xml b/core/res/res/values-iw/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-iw/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-iw/required_apps_managed_user.xml b/core/res/res/values-iw/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-iw/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ja/required_apps_managed_device.xml b/core/res/res/values-ja/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-ja/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ja/required_apps_managed_profile.xml b/core/res/res/values-ja/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-ja/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ja/required_apps_managed_user.xml b/core/res/res/values-ja/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-ja/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-kk/required_apps_managed_device.xml b/core/res/res/values-kk/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-kk/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-kk/required_apps_managed_profile.xml b/core/res/res/values-kk/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-kk/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-kk/required_apps_managed_user.xml b/core/res/res/values-kk/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-kk/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-km/required_apps_managed_device.xml b/core/res/res/values-km/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-km/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-km/required_apps_managed_profile.xml b/core/res/res/values-km/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-km/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-km/required_apps_managed_user.xml b/core/res/res/values-km/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-km/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index b2778a1..7be15f1 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1696,9 +1696,9 @@
<string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"សំណើរ USSD ត្រូវបានកែសម្រួលទៅតាមសំណើរការហៅទូរស័ព្ទ។"</string>
<string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"សំណើរ USSD ត្រូវបានកែសម្រួលទៅតាមសំណើរ SS។"</string>
<string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"សំណើរ USSD ត្រូវបានកែសម្រួលទៅតាមសំណើរ USSD ថ្មី។្"</string>
- <string name="stk_cc_ussd_to_dial_video" msgid="585340552561515305">"សំណើ USSD ត្រូវបានកែសម្រួលទៅជាសំណើ Video DIAL ។"</string>
+ <string name="stk_cc_ussd_to_dial_video" msgid="585340552561515305">"សំណើ USSD ត្រូវបានកែប្រែទៅជាសំណើ DIAL ជាវីដេអូ។"</string>
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"សំណើរ SS ត្រូវបានកែសម្រួលទៅតាមសំណើរការហៅទូរស័ព្ទ។"</string>
- <string name="stk_cc_ss_to_dial_video" msgid="4306210904450719045">"សំណើ SS ត្រូវបានកែសម្រួលទៅជាសំណើ Video DIAL ។"</string>
+ <string name="stk_cc_ss_to_dial_video" msgid="4306210904450719045">"សំណើ SS ត្រូវបានកែប្រែទៅជាសំណើ DIAL ជាវីដេអូ។"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"សំណើរ SS ត្រូវបានកែសម្រួលទៅតាមសំណើរ USSD។"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"សំណើរ SS ត្រូវបានកែសម្រួលទៅតាមសំណើរ SS ថ្មី។"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ប្រវត្តិរូបការងារ"</string>
diff --git a/core/res/res/values-kn/required_apps_managed_device.xml b/core/res/res/values-kn/required_apps_managed_device.xml
new file mode 100644
index 0000000..e15b0b0
--- /dev/null
+++ b/core/res/res/values-kn/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.ಸೆಟ್ಟಿಂಗ್ಗಳು"</item>
+ <item msgid="7004798084799227194">"com.android.ಸಂಪರ್ಕಗಳು"</item>
+ <item msgid="5782220690863647256">"com.android.ಡಯಲರ್"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.ಒದಗಿಸುವವರು.ಡೌನ್ಲೋಡ್ಗಳು"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-kn/required_apps_managed_profile.xml b/core/res/res/values-kn/required_apps_managed_profile.xml
new file mode 100644
index 0000000..92ab682
--- /dev/null
+++ b/core/res/res/values-kn/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.ಸಂಪರ್ಕಗಳು"</item>
+ <item msgid="4633145750237794002">"com.android.ಸೆಟ್ಟಿಂಗ್ಗಳು"</item>
+ <item msgid="6518205098643077579">"com.android.ಒದಗಿಸುವವರು.ಡೌನ್ಲೋಡ್ಗಳು"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-kn/required_apps_managed_user.xml b/core/res/res/values-kn/required_apps_managed_user.xml
new file mode 100644
index 0000000..0c59edd
--- /dev/null
+++ b/core/res/res/values-kn/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.ಸೆಟ್ಟಿಂಗ್ಗಳು"</item>
+ <item msgid="2250259015310893915">"com.android.ಸಂಪರ್ಕಗಳು"</item>
+ <item msgid="7166574999426592423">"com.android.ಡಯಲರ್"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.ಒದಗಿಸುವವರು.ಡೌನ್ಲೋಡ್ಗಳು"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 4485561..99db9e6 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1695,11 +1695,9 @@
<string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD ವಿನಂತಿಯನ್ನು DIAL ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
<string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD ವಿನಂತಿಯನ್ನು SS ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
<string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD ವಿನಂತಿಯನ್ನು ಹೊಸ USSD ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
- <!-- no translation found for stk_cc_ussd_to_dial_video (585340552561515305) -->
- <skip />
+ <string name="stk_cc_ussd_to_dial_video" msgid="585340552561515305">"USSD ವಿನಂತಿಯನ್ನು ವೀಡಿಯೊ DIAL ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS ವಿನಂತಿಯನ್ನು DIAL ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
- <!-- no translation found for stk_cc_ss_to_dial_video (4306210904450719045) -->
- <skip />
+ <string name="stk_cc_ss_to_dial_video" msgid="4306210904450719045">"SS ವಿನಂತಿಯನ್ನು ವೀಡಿಯೊ DIAL ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS ವಿನಂತಿಯನ್ನು USSD ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS ವಿನಂತಿಯನ್ನು ಹೊಸ SS ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್"</string>
diff --git a/core/res/res/values-ko/required_apps_managed_device.xml b/core/res/res/values-ko/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-ko/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ko/required_apps_managed_profile.xml b/core/res/res/values-ko/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-ko/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ko/required_apps_managed_user.xml b/core/res/res/values-ko/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-ko/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ky/required_apps_managed_device.xml b/core/res/res/values-ky/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-ky/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ky/required_apps_managed_profile.xml b/core/res/res/values-ky/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-ky/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ky/required_apps_managed_user.xml b/core/res/res/values-ky/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-ky/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index e580a59..cfa05de 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -212,7 +212,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"Кубатын өчүрүү"</string>
<string name="global_action_emergency" msgid="7112311161137421166">"Тез жардам"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Ката тууралуу билдирүү"</string>
- <string name="global_action_logout" msgid="935179188218826050">"Сессияны аяктоо"</string>
+ <string name="global_action_logout" msgid="935179188218826050">"Сеансты бүтүрүү"</string>
<string name="bugreport_title" msgid="2667494803742548533">"Ката тууралуу билдирүү түзүү"</string>
<string name="bugreport_message" msgid="398447048750350456">"Ушуну менен түзмөгүңүздүн учурдагы абалы тууралуу маалымат топтолуп, электрондук почта аркылуу жөнөтүлөт. Отчет даяр болгуча бир аз күтө туруңуз."</string>
<string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактивдүү кабар"</string>
@@ -1502,7 +1502,7 @@
<string name="disable_accessibility_shortcut" msgid="627625354248453445">"Кыска жолду өчүрүү"</string>
<string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Кыска жолду колдонуу"</string>
<string name="color_inversion_feature_name" msgid="4231186527799958644">"Түстү инверсиялоо"</string>
- <string name="color_correction_feature_name" msgid="6779391426096954933">"Түстү түзөтүү"</string>
+ <string name="color_correction_feature_name" msgid="6779391426096954933">"Түсүн тууралоо"</string>
<string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Атайын мүмкүнчүлүктөр кыска жолу <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын күйгүздү"</string>
<string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Атайын мүмкүнчүлүктөр кыска жолу <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын өчүрдү"</string>
<string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштетиле турган функцияны тандаңыз:"</string>
diff --git a/core/res/res/values-lo/required_apps_managed_device.xml b/core/res/res/values-lo/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-lo/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-lo/required_apps_managed_profile.xml b/core/res/res/values-lo/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-lo/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-lo/required_apps_managed_user.xml b/core/res/res/values-lo/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-lo/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-lt/required_apps_managed_device.xml b/core/res/res/values-lt/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-lt/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-lt/required_apps_managed_profile.xml b/core/res/res/values-lt/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-lt/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-lt/required_apps_managed_user.xml b/core/res/res/values-lt/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-lt/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-lv/required_apps_managed_device.xml b/core/res/res/values-lv/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-lv/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-lv/required_apps_managed_profile.xml b/core/res/res/values-lv/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-lv/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-lv/required_apps_managed_user.xml b/core/res/res/values-lv/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-lv/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mk/required_apps_managed_device.xml b/core/res/res/values-mk/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-mk/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mk/required_apps_managed_profile.xml b/core/res/res/values-mk/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-mk/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mk/required_apps_managed_user.xml b/core/res/res/values-mk/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-mk/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ml/required_apps_managed_device.xml b/core/res/res/values-ml/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-ml/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ml/required_apps_managed_profile.xml b/core/res/res/values-ml/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-ml/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ml/required_apps_managed_user.xml b/core/res/res/values-ml/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-ml/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 2595f94..fc958fa 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1695,11 +1695,9 @@
<string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD അഭ്യർത്ഥന, DIAL അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
<string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD അഭ്യർത്ഥന, SS അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
<string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD അഭ്യർത്ഥന, പുതിയ USSD അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
- <!-- no translation found for stk_cc_ussd_to_dial_video (585340552561515305) -->
- <skip />
+ <string name="stk_cc_ussd_to_dial_video" msgid="585340552561515305">"USSD അഭ്യർത്ഥന, വീഡിയോ DIAL അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS അഭ്യർത്ഥന, DIAL അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
- <!-- no translation found for stk_cc_ss_to_dial_video (4306210904450719045) -->
- <skip />
+ <string name="stk_cc_ss_to_dial_video" msgid="4306210904450719045">"SS അഭ്യർത്ഥന, വീഡിയോ DIAL അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS അഭ്യർത്ഥന, USSD അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS അഭ്യർത്ഥന, പുതിയ SS അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
diff --git a/core/res/res/values-mn/required_apps_managed_device.xml b/core/res/res/values-mn/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-mn/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mn/required_apps_managed_profile.xml b/core/res/res/values-mn/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-mn/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mn/required_apps_managed_user.xml b/core/res/res/values-mn/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-mn/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mr/required_apps_managed_device.xml b/core/res/res/values-mr/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-mr/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mr/required_apps_managed_profile.xml b/core/res/res/values-mr/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-mr/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mr/required_apps_managed_user.xml b/core/res/res/values-mr/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-mr/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ms/required_apps_managed_device.xml b/core/res/res/values-ms/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-ms/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ms/required_apps_managed_profile.xml b/core/res/res/values-ms/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-ms/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ms/required_apps_managed_user.xml b/core/res/res/values-ms/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-ms/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-nb/required_apps_managed_device.xml b/core/res/res/values-nb/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-nb/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-nb/required_apps_managed_profile.xml b/core/res/res/values-nb/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-nb/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-nb/required_apps_managed_user.xml b/core/res/res/values-nb/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-nb/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ne/required_apps_managed_device.xml b/core/res/res/values-ne/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-ne/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ne/required_apps_managed_profile.xml b/core/res/res/values-ne/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-ne/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ne/required_apps_managed_user.xml b/core/res/res/values-ne/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-ne/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 9223c76..f0a45a3 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1232,8 +1232,8 @@
<string name="ext_media_unmountable_notification_message" msgid="2343202057122495773">"<xliff:g id="NAME">%s</xliff:g> त्रुटिपूर्ण छ। समाधान गर्न ट्याप गर्नुहोस्।"</string>
<string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> बिग्रेको छ। समाधान गर्न चयन गर्नुहोस्।"</string>
<string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"असमर्थित <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"यस यन्त्रले यस <xliff:g id="NAME">%s</xliff:g> लाई समर्थन गर्दैन। एक समर्थित ढाँचामा सेट अप गर्न ट्याप गर्नुहोस्।"</string>
- <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"यो यन्त्रले यस <xliff:g id="NAME">%s</xliff:g> लाई समर्थन गर्दैन। एक समर्थित ढाँचामा सेट अप गर्न चयन गर्नुहोस्।"</string>
+ <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"यस यन्त्रले यस <xliff:g id="NAME">%s</xliff:g> लाई समर्थन गर्दैन। एक समर्थित ढाँचामा सेटअप गर्न ट्याप गर्नुहोस्।"</string>
+ <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"यो यन्त्रले यस <xliff:g id="NAME">%s</xliff:g> लाई समर्थन गर्दैन। एक समर्थित ढाँचामा सेटअप गर्न चयन गर्नुहोस्।"</string>
<string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> अप्रत्याशित रूपमा निकालियो"</string>
<string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"डेटा हराउनबाट जोगाउन निकाल्नु अघि <xliff:g id="NAME">%s</xliff:g> अनमाउन्ट गर्नुहोस्"</string>
<string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"निकालियो <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1318,7 +1318,7 @@
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"कार मोड सक्षम पारियो।"</string>
<string name="car_mode_disable_notification_message" msgid="6301524980144350051">"कार मोडबाट बाहिर निस्कन ट्याप गर्नुहोस्।"</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"टेथर गर्ने वा हटस्पट सक्रिय"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"सेट अप गर्न ट्याप गर्नुहोस्।"</string>
+ <string name="tethered_notification_message" msgid="2113628520792055377">"सेटअप गर्न ट्याप गर्नुहोस्।"</string>
<string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिङलाई असक्षम पारिएको छ"</string>
<string name="disable_tether_notification_message" msgid="2913366428516852495">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string>
<string name="back_button_label" msgid="2300470004503343439">"पछाडि"</string>
diff --git a/core/res/res/values-pa/required_apps_managed_device.xml b/core/res/res/values-pa/required_apps_managed_device.xml
new file mode 100644
index 0000000..faadc50
--- /dev/null
+++ b/core/res/res/values-pa/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.download"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-pa/required_apps_managed_profile.xml b/core/res/res/values-pa/required_apps_managed_profile.xml
new file mode 100644
index 0000000..537a80c
--- /dev/null
+++ b/core/res/res/values-pa/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.download"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-pa/required_apps_managed_user.xml b/core/res/res/values-pa/required_apps_managed_user.xml
new file mode 100644
index 0000000..e69bbbc
--- /dev/null
+++ b/core/res/res/values-pa/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.download"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 283701e..b5b6a00 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1695,11 +1695,9 @@
<string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD ਬੇਨਤੀ DIAL ਬੇਨਤੀ ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
<string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD ਬੇਨਤੀ SS ਬੇਨਤੀ ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
<string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD ਬੇਨਤੀ ਨਵੀਂ USSD ਬੇਨਤੀ ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
- <!-- no translation found for stk_cc_ussd_to_dial_video (585340552561515305) -->
- <skip />
+ <string name="stk_cc_ussd_to_dial_video" msgid="585340552561515305">"USSD ਬੇਨਤੀ ਨੂੰ ਸੋਧ ਕੇ ਵੀਡੀਓ ਡਾਇਲ ਬੇਨਤੀ ਵਿੱਚ ਬਦਲਿਆ ਗਿਆ।"</string>
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS ਬੇਨਤੀ DIAL ਬੇਨਤੀ ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
- <!-- no translation found for stk_cc_ss_to_dial_video (4306210904450719045) -->
- <skip />
+ <string name="stk_cc_ss_to_dial_video" msgid="4306210904450719045">"SS ਬੇਨਤੀ ਨੂੰ ਸੋਧ ਕੇ ਵੀਡੀਓ ਡਾਇਲ ਬੇਨਤੀ ਵਿੱਚ ਬਦਲਿਆ ਗਿਆ।"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS ਬੇਨਤੀ USSD ਬੇਨਤੀ ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS ਬੇਨਤੀ ਨਵੀਂ SS ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
diff --git a/core/res/res/values-pl/required_apps_managed_device.xml b/core/res/res/values-pl/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-pl/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-pl/required_apps_managed_profile.xml b/core/res/res/values-pl/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-pl/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-pl/required_apps_managed_user.xml b/core/res/res/values-pl/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-pl/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-pt-rPT/required_apps_managed_device.xml b/core/res/res/values-pt-rPT/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-pt-rPT/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-pt-rPT/required_apps_managed_profile.xml b/core/res/res/values-pt-rPT/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-pt-rPT/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-pt-rPT/required_apps_managed_user.xml b/core/res/res/values-pt-rPT/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-pt-rPT/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 434b50b..dc2d6e4 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -381,7 +381,7 @@
<string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"Esta aplicação pode ler todos os eventos do calendário armazenados no seu tablet e partilhar ou guardar os dados do calendário."</string>
<string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"Esta aplicação pode ler todos os eventos do calendário armazenados na sua TV e partilhar ou guardar os dados do calendário."</string>
<string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"Esta aplicação pode ler todos os eventos do calendário armazenados no seu telemóvel e partilhar ou guardar os dados do calendário."</string>
- <string name="permlab_writeCalendar" msgid="8438874755193825647">"adicionar ou modificar eventos do calendário e enviar e-mail a convidados sem o conhecimento dos proprietários"</string>
+ <string name="permlab_writeCalendar" msgid="8438874755193825647">"adicionar ou modificar eventos do calendário e enviar email a convidados sem o conhecimento dos proprietários"</string>
<string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"Esta aplicação pode adicionar, remover ou alterar eventos do calendário no seu tablet. Esta aplicação pode enviar mensagens que parecem vir de proprietários do calendário ou alterar eventos sem notificar os respetivos proprietários."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"Esta aplicação pode adicionar, remover ou alterar eventos do calendário na sua TV. Esta aplicação pode enviar mensagens que parecem vir de proprietários do calendário ou alterar eventos sem notificar os respetivos proprietários."</string>
<string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"Esta aplicação pode adicionar, remover ou alterar eventos do calendário no seu telemóvel. Esta aplicação pode enviar mensagens que parecem vir de proprietários do calendário ou alterar eventos sem notificar os respetivos proprietários."</string>
@@ -756,7 +756,7 @@
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Desbloqueio da conta"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Demasiadas tentativas para desenhar sequência"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Para desbloquear, inicie sessão com a Conta Google."</string>
- <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nome de utilizador (e-mail)"</string>
+ <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nome de utilizador (email)"</string>
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Palavra-passe"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Iniciar sessão"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nome de utilizador ou palavra-passe inválidos."</string>
diff --git a/core/res/res/values-ro/required_apps_managed_device.xml b/core/res/res/values-ro/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-ro/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ro/required_apps_managed_profile.xml b/core/res/res/values-ro/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-ro/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ro/required_apps_managed_user.xml b/core/res/res/values-ro/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-ro/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sk/required_apps_managed_device.xml b/core/res/res/values-sk/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-sk/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sk/required_apps_managed_profile.xml b/core/res/res/values-sk/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-sk/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sk/required_apps_managed_user.xml b/core/res/res/values-sk/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-sk/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sl/required_apps_managed_device.xml b/core/res/res/values-sl/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-sl/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sl/required_apps_managed_profile.xml b/core/res/res/values-sl/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-sl/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sl/required_apps_managed_user.xml b/core/res/res/values-sl/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-sl/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sq/required_apps_managed_device.xml b/core/res/res/values-sq/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-sq/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sq/required_apps_managed_profile.xml b/core/res/res/values-sq/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-sq/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sq/required_apps_managed_user.xml b/core/res/res/values-sq/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-sq/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sr/required_apps_managed_device.xml b/core/res/res/values-sr/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-sr/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sr/required_apps_managed_profile.xml b/core/res/res/values-sr/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-sr/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sr/required_apps_managed_user.xml b/core/res/res/values-sr/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-sr/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sv/required_apps_managed_device.xml b/core/res/res/values-sv/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-sv/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sv/required_apps_managed_profile.xml b/core/res/res/values-sv/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-sv/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sv/required_apps_managed_user.xml b/core/res/res/values-sv/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-sv/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sw/required_apps_managed_device.xml b/core/res/res/values-sw/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-sw/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sw/required_apps_managed_profile.xml b/core/res/res/values-sw/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-sw/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-sw/required_apps_managed_user.xml b/core/res/res/values-sw/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-sw/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ta/required_apps_managed_device.xml b/core/res/res/values-ta/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-ta/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ta/required_apps_managed_profile.xml b/core/res/res/values-ta/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-ta/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ta/required_apps_managed_user.xml b/core/res/res/values-ta/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-ta/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index c1526f3..c517223 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1695,11 +1695,9 @@
<string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD கோரிக்கையானது DIAL கோரிக்கைக்கு மாற்றப்பட்டது."</string>
<string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD கோரிக்கையானது SS கோரிக்கைக்கு மாற்றப்பட்டது."</string>
<string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD கோரிக்கையானது புதிய USSD கோரிக்கைக்கு மாற்றப்பட்டது."</string>
- <!-- no translation found for stk_cc_ussd_to_dial_video (585340552561515305) -->
- <skip />
+ <string name="stk_cc_ussd_to_dial_video" msgid="585340552561515305">"USSD கோரிக்கையானது வீடியோ DIAL கோரிக்கைக்கு மாற்றப்பட்டது."</string>
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS கோரிக்கையானது DIAL கோரிக்கைக்கு மாற்றப்பட்டது."</string>
- <!-- no translation found for stk_cc_ss_to_dial_video (4306210904450719045) -->
- <skip />
+ <string name="stk_cc_ss_to_dial_video" msgid="4306210904450719045">"SS கோரிக்கையானது வீடியோ DIAL கோரிக்கைக்கு மாற்றப்பட்டது."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS கோரிக்கையானது USSD கோரிக்கைக்கு மாற்றப்பட்டது."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS கோரிக்கையானது புதிய SS கோரிக்கைக்கு மாற்றப்பட்டது."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"பணி சுயவிவரம்"</string>
diff --git a/core/res/res/values-te/required_apps_managed_device.xml b/core/res/res/values-te/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-te/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-te/required_apps_managed_profile.xml b/core/res/res/values-te/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-te/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-te/required_apps_managed_user.xml b/core/res/res/values-te/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-te/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index a96bcaf..fd103bc 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1695,11 +1695,9 @@
<string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD అభ్యర్థన డయల్ అభ్యర్థనగా సవరించబడింది."</string>
<string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD అభ్యర్థన SS అభ్యర్థనగా సవరించబడింది."</string>
<string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD అభ్యర్థన కొత్త USSD అభ్యర్థనగా సవరించబడింది."</string>
- <!-- no translation found for stk_cc_ussd_to_dial_video (585340552561515305) -->
- <skip />
+ <string name="stk_cc_ussd_to_dial_video" msgid="585340552561515305">"USSD అభ్యర్థన వీడియో డయల్ అభ్యర్థనగా సవరించబడింది."</string>
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS అభ్యర్థన డయల్ అభ్యర్థనగా సవరించబడింది."</string>
- <!-- no translation found for stk_cc_ss_to_dial_video (4306210904450719045) -->
- <skip />
+ <string name="stk_cc_ss_to_dial_video" msgid="4306210904450719045">"SS అభ్యర్థన వీడియో డయల్ అభ్యర్థనగా సవరించబడింది."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS అభ్యర్థన USSD అభ్యర్థనగా సవరించబడింది."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS అభ్యర్థన కొత్త SS అభ్యర్థనగా సవరించబడింది."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"కార్యాలయ ప్రొఫైల్"</string>
diff --git a/core/res/res/values-th/required_apps_managed_device.xml b/core/res/res/values-th/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-th/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-th/required_apps_managed_profile.xml b/core/res/res/values-th/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-th/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-th/required_apps_managed_user.xml b/core/res/res/values-th/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-th/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-tl/required_apps_managed_device.xml b/core/res/res/values-tl/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-tl/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-tl/required_apps_managed_profile.xml b/core/res/res/values-tl/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-tl/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-tl/required_apps_managed_user.xml b/core/res/res/values-tl/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-tl/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-tr/required_apps_managed_device.xml b/core/res/res/values-tr/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-tr/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-tr/required_apps_managed_profile.xml b/core/res/res/values-tr/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-tr/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-tr/required_apps_managed_user.xml b/core/res/res/values-tr/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-tr/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ur/required_apps_managed_device.xml b/core/res/res/values-ur/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-ur/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ur/required_apps_managed_profile.xml b/core/res/res/values-ur/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-ur/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ur/required_apps_managed_user.xml b/core/res/res/values-ur/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-ur/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 2155b34..2771432 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1695,11 +1695,9 @@
<string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD درخواست میں ترمیم کر کے DIAL درخواست بنا دی گئی ہے۔"</string>
<string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD درخواست میں ترمیم کر کے SS درخواست بنا دی گئی ہے۔"</string>
<string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD درخواست میں ترمیم کر کے نئی USSD درخواست بنا دی گئی ہے۔"</string>
- <!-- no translation found for stk_cc_ussd_to_dial_video (585340552561515305) -->
- <skip />
+ <string name="stk_cc_ussd_to_dial_video" msgid="585340552561515305">"USSD درخواست کو ویڈیو DIAL درخواست میں تبدیل کر دیا گیا ہے۔"</string>
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS درخواست میں ترمیم کر کے DIAL درخواست بنا دی گئی ہے۔"</string>
- <!-- no translation found for stk_cc_ss_to_dial_video (4306210904450719045) -->
- <skip />
+ <string name="stk_cc_ss_to_dial_video" msgid="4306210904450719045">"SS درخواست کو ویڈیو DIAL درخواست میں تبدیل کر دیا گیا ہے۔"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS درخواست میں ترمیم کر کے USSD درخواست بنا دی گئی ہے۔"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS درخواست میں ترمیم کر کے نئی SS درخواست بنا دی گئی ہے۔"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"دفتری پروفائل"</string>
diff --git a/core/res/res/values-uz/required_apps_managed_device.xml b/core/res/res/values-uz/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-uz/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-uz/required_apps_managed_profile.xml b/core/res/res/values-uz/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-uz/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-uz/required_apps_managed_user.xml b/core/res/res/values-uz/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-uz/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-vi/required_apps_managed_device.xml b/core/res/res/values-vi/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-vi/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-vi/required_apps_managed_profile.xml b/core/res/res/values-vi/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-vi/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-vi/required_apps_managed_user.xml b/core/res/res/values-vi/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-vi/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-zh-rCN/required_apps_managed_device.xml b/core/res/res/values-zh-rCN/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-zh-rCN/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-zh-rCN/required_apps_managed_profile.xml b/core/res/res/values-zh-rCN/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-zh-rCN/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-zh-rCN/required_apps_managed_user.xml b/core/res/res/values-zh-rCN/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-zh-rCN/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-zh-rHK/required_apps_managed_device.xml b/core/res/res/values-zh-rHK/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-zh-rHK/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-zh-rHK/required_apps_managed_profile.xml b/core/res/res/values-zh-rHK/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-zh-rHK/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-zh-rHK/required_apps_managed_user.xml b/core/res/res/values-zh-rHK/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-zh-rHK/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-zh-rTW/required_apps_managed_device.xml b/core/res/res/values-zh-rTW/required_apps_managed_device.xml
new file mode 100644
index 0000000..9044fcc
--- /dev/null
+++ b/core/res/res/values-zh-rTW/required_apps_managed_device.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_device">
+ <item msgid="1104492179978792509">"com.android.settings"</item>
+ <item msgid="7004798084799227194">"com.android.contacts"</item>
+ <item msgid="5782220690863647256">"com.android.dialer"</item>
+ <item msgid="5746338511138092673">"com.android.stk"</item>
+ <item msgid="1712599182168590664">"com.android.providers.downloads"</item>
+ <item msgid="2858239953396384085">"com.android.providers.downloads.ui"</item>
+ <item msgid="3892021562839042708">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-zh-rTW/required_apps_managed_profile.xml b/core/res/res/values-zh-rTW/required_apps_managed_profile.xml
new file mode 100644
index 0000000..4296b0d
--- /dev/null
+++ b/core/res/res/values-zh-rTW/required_apps_managed_profile.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_profile">
+ <item msgid="1457364287544474838">"com.android.contacts"</item>
+ <item msgid="4633145750237794002">"com.android.settings"</item>
+ <item msgid="6518205098643077579">"com.android.providers.downloads"</item>
+ <item msgid="9003577256117829525">"com.android.providers.downloads.ui"</item>
+ <item msgid="6106837921940099371">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-zh-rTW/required_apps_managed_user.xml b/core/res/res/values-zh-rTW/required_apps_managed_user.xml
new file mode 100644
index 0000000..1a7ade9
--- /dev/null
+++ b/core/res/res/values-zh-rTW/required_apps_managed_user.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="required_apps_managed_user">
+ <item msgid="4823915868435007499">"com.android.settings"</item>
+ <item msgid="2250259015310893915">"com.android.contacts"</item>
+ <item msgid="7166574999426592423">"com.android.dialer"</item>
+ <item msgid="7306937186458176744">"com.android.stk"</item>
+ <item msgid="7415441588151512455">"com.android.providers.downloads"</item>
+ <item msgid="2277950048461066377">"com.android.providers.downloads.ui"</item>
+ <item msgid="8640522622655589373">"com.android.documentsui"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 51ffa60..64febf1 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4442,7 +4442,7 @@
<attr name="textColor" />
<!-- Size of the text. Recommended dimension type for text is "sp" for scaled-pixels (example: 15sp). -->
<attr name="textSize" />
- <!-- Style (bold, italic, bolditalic) for the text. -->
+ <!-- Style (normal, bold, italic, bold|italic) for the text. -->
<attr name="textStyle" />
<!-- Typeface (normal, sans, serif, monospace) for the text. -->
<attr name="typeface" />
@@ -4527,7 +4527,7 @@
<attr name="textScaleX" format="float" />
<!-- Typeface (normal, sans, serif, monospace) for the text. -->
<attr name="typeface" />
- <!-- Style (bold, italic, bolditalic) for the text. -->
+ <!-- Style (normal, bold, italic, bold|italic) for the text. -->
<attr name="textStyle" />
<!-- Font family (named by string or as a font resource reference) for the text. -->
<attr name="fontFamily" />
@@ -7729,6 +7729,10 @@
wallpaper. -->
<attr name="showMetadataInPreview" format="boolean" />
+ <!-- Wallpapers optimized and capable of drawing in ambient mode will return true.
+ @hide -->
+ <attr name="supportsAmbientMode" format="boolean" />
+
</declare-styleable>
<!-- Use <code>dream</code> as the root tag of the XML resource that
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 4b1f2da..e4de526 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -513,6 +513,12 @@
}
@Override
+ public void dumpMemInfoProto(ParcelFileDescriptor parcelFileDescriptor,
+ Debug.MemoryInfo memoryInfo, boolean b, boolean b1, boolean b2,
+ boolean b3, String[] strings) throws RemoteException {
+ }
+
+ @Override
public void dumpGfxInfo(ParcelFileDescriptor parcelFileDescriptor, String[] strings)
throws RemoteException {
}
diff --git a/core/tests/coretests/src/android/text/DynamicLayoutTest.java b/core/tests/coretests/src/android/text/DynamicLayoutTest.java
index aa9aed8..ea954f6 100644
--- a/core/tests/coretests/src/android/text/DynamicLayoutTest.java
+++ b/core/tests/coretests/src/android/text/DynamicLayoutTest.java
@@ -30,6 +30,7 @@
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.text.style.ReplacementSpan;
+import android.util.ArraySet;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -190,6 +191,27 @@
}
@Test
+ public void testReflow_afterSpannableEdit() {
+ final String text = "a\nb:\uD83C\uDF1A c \n\uD83C\uDF1A";
+ final int length = text.length();
+ final SpannableStringBuilder spannable = new SpannableStringBuilder(text);
+ spannable.setSpan(new MockReplacementSpan(), 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ spannable.setSpan(new MockReplacementSpan(), 10, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ final DynamicLayout layout = new DynamicLayout(spannable, new TextPaint(), WIDTH,
+ ALIGN_NORMAL, 1.0f /*spacingMultiplier*/, 0f /*spacingAdd*/, false /*includepad*/);
+
+ spannable.delete(8, 9);
+ spannable.replace(7, 8, "ch");
+
+ layout.reflow(spannable, 0, length, length);
+ final ArraySet<Integer> blocks = layout.getBlocksAlwaysNeedToBeRedrawn();
+ for (Integer value : blocks) {
+ assertTrue("Block index should not be negative", value >= 0);
+ }
+ }
+
+ @Test
public void testFallbackLineSpacing() {
// All glyphs in the fonts are 1em wide.
final String[] testFontFiles = {
diff --git a/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java b/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java
index f1a730a..d0f2d46 100644
--- a/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java
+++ b/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.text.style.BulletSpan;
@@ -30,6 +31,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+@Presubmit
@SmallTest
@RunWith(AndroidJUnit4.class)
public class SpannableStringBuilderTest extends SpannableTest {
diff --git a/core/tests/coretests/src/android/text/format/FormatterTest.java b/core/tests/coretests/src/android/text/format/FormatterTest.java
index 2d94016..9c544f4 100644
--- a/core/tests/coretests/src/android/text/format/FormatterTest.java
+++ b/core/tests/coretests/src/android/text/format/FormatterTest.java
@@ -23,6 +23,7 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.icu.util.MeasureUnit;
+import android.platform.test.annotations.Presubmit;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -36,7 +37,7 @@
import java.util.Locale;
import java.util.Set;
-
+@Presubmit
@SmallTest
@RunWith(AndroidJUnit4.class)
public class FormatterTest {
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
index 9092c85..a8de374 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
@@ -16,10 +16,9 @@
package android.view.textclassifier;
+import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import android.os.LocaleList;
@@ -34,8 +33,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.Collection;
-
@SmallTest
@RunWith(AndroidJUnit4.class)
public class TextClassificationManagerTest {
@@ -166,20 +163,50 @@
}
@Test
- public void testGenerateLinks() {
+ public void testGenerateLinks_phone() {
if (isTextClassifierDisabled()) return;
+ String text = "The number is +12122537077. See you tonight!";
+ assertThat(mClassifier.generateLinks(text, null),
+ isTextLinksContaining(text, "+12122537077", TextClassifier.TYPE_PHONE));
+ }
- checkGenerateLinksFindsLink(
- "The number is +12122537077. See you tonight!",
- "+12122537077",
- TextClassifier.TYPE_PHONE);
+ @Test
+ public void testGenerateLinks_exclude() {
+ if (isTextClassifierDisabled()) return;
+ String text = "The number is +12122537077. See you tonight!";
+ assertThat(mClassifier.generateLinks(text, mLinksOptions.setEntityConfig(
+ new TextClassifier.EntityConfig(TextClassifier.ENTITY_PRESET_ALL)
+ .excludeEntities(TextClassifier.TYPE_PHONE))),
+ not(isTextLinksContaining(text, "+12122537077", TextClassifier.TYPE_PHONE)));
+ }
- checkGenerateLinksFindsLink(
- "The address is 1600 Amphitheater Parkway, Mountain View, CA. See you tonight!",
- "1600 Amphitheater Parkway, Mountain View, CA",
- TextClassifier.TYPE_ADDRESS);
+ @Test
+ public void testGenerateLinks_none_config() {
+ if (isTextClassifierDisabled()) return;
+ String text = "The number is +12122537077. See you tonight!";
+ assertThat(mClassifier.generateLinks(text, mLinksOptions.setEntityConfig(
+ new TextClassifier.EntityConfig(TextClassifier.ENTITY_PRESET_NONE))),
+ not(isTextLinksContaining(text, "+12122537077", TextClassifier.TYPE_PHONE)));
+ }
- // TODO: Add more entity types when the model supports them.
+ @Test
+ public void testGenerateLinks_address() {
+ if (isTextClassifierDisabled()) return;
+ String text = "The address is 1600 Amphitheater Parkway, Mountain View, CA. See you!";
+ assertThat(mClassifier.generateLinks(text, null),
+ isTextLinksContaining(text, "1600 Amphitheater Parkway, Mountain View, CA",
+ TextClassifier.TYPE_ADDRESS));
+ }
+
+ @Test
+ public void testGenerateLinks_include() {
+ if (isTextClassifierDisabled()) return;
+ String text = "The address is 1600 Amphitheater Parkway, Mountain View, CA. See you!";
+ assertThat(mClassifier.generateLinks(text, mLinksOptions.setEntityConfig(
+ new TextClassifier.EntityConfig(TextClassifier.ENTITY_PRESET_NONE)
+ .includeEntities(TextClassifier.TYPE_ADDRESS))),
+ isTextLinksContaining(text, "1600 Amphitheater Parkway, Mountain View, CA",
+ TextClassifier.TYPE_ADDRESS));
}
@Test
@@ -193,25 +220,6 @@
return mClassifier == TextClassifier.NO_OP;
}
- private void checkGenerateLinksFindsLink(String text, String classifiedText, String type) {
- assertTrue(text.contains(classifiedText));
- int startIndex = text.indexOf(classifiedText);
- int endIndex = startIndex + classifiedText.length();
-
- Collection<TextLinks.TextLink> links = mClassifier.generateLinks(text, mLinksOptions)
- .getLinks();
- for (TextLinks.TextLink link : links) {
- if (text.subSequence(link.getStart(), link.getEnd()).equals(classifiedText)) {
- assertEquals(type, link.getEntity(0));
- assertEquals(startIndex, link.getStart());
- assertEquals(endIndex, link.getEnd());
- assertTrue(link.getConfidenceScore(type) > 0);
- return;
- }
- }
- fail(); // Subsequence was not identified.
- }
-
private static Matcher<TextSelection> isTextSelection(
final int startIndex, final int endIndex, final String type) {
return new BaseMatcher<TextSelection>() {
@@ -240,6 +248,31 @@
};
}
+ private static Matcher<TextLinks> isTextLinksContaining(
+ final String text, final String substring, final String type) {
+ return new BaseMatcher<TextLinks>() {
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("text=").appendValue(text)
+ .appendText(", substring=").appendValue(substring)
+ .appendText(", type=").appendValue(type);
+ }
+
+ @Override
+ public boolean matches(Object o) {
+ if (o instanceof TextLinks) {
+ for (TextLinks.TextLink link : ((TextLinks) o).getLinks()) {
+ if (text.subSequence(link.getStart(), link.getEnd()).equals(substring)) {
+ return type.equals(link.getEntity(0));
+ }
+ }
+ }
+ return false;
+ }
+ };
+ }
+
private static Matcher<TextClassification> isTextClassification(
final String text, final String type, final String intentUri) {
return new BaseMatcher<TextClassification>() {
diff --git a/core/tests/privacytests/Android.mk b/core/tests/privacytests/Android.mk
new file mode 100644
index 0000000..7b11225
--- /dev/null
+++ b/core/tests/privacytests/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Include all test java files.
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := junit rappor-tests android-support-test
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_PACKAGE_NAME := FrameworksPrivacyLibraryTests
+
+include $(BUILD_PACKAGE)
diff --git a/core/tests/privacytests/AndroidManifest.xml b/core/tests/privacytests/AndroidManifest.xml
new file mode 100644
index 0000000..a0e5281
--- /dev/null
+++ b/core/tests/privacytests/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.privacy">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.frameworks.coretests.privacy"
+ android:label="Frameworks Privacy Library Tests" />
+
+</manifest>
diff --git a/core/tests/privacytests/src/android/privacy/LongitudinalReportingEncoderTest.java b/core/tests/privacytests/src/android/privacy/LongitudinalReportingEncoderTest.java
new file mode 100644
index 0000000..9166438
--- /dev/null
+++ b/core/tests/privacytests/src/android/privacy/LongitudinalReportingEncoderTest.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.privacy;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.privacy.internal.longitudinalreporting.LongitudinalReportingConfig;
+import android.privacy.internal.longitudinalreporting.LongitudinalReportingEncoder;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+
+/**
+ * Unit test for the {@link LongitudinalReportingEncoder}.
+ *
+ * As {@link LongitudinalReportingEncoder} is based on Rappor,
+ * most cases are covered by Rappor tests already.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LongitudinalReportingEncoderTest {
+
+ @Test
+ public void testLongitudinalReportingEncoder_config() throws Exception {
+ final LongitudinalReportingConfig config = new LongitudinalReportingConfig(
+ "Foo", // encoderId
+ 0.4, // probabilityF
+ 0.25, // probabilityP
+ 1); // probabilityQ
+ final LongitudinalReportingEncoder encoder =
+ LongitudinalReportingEncoder.createInsecureEncoderForTest(
+ config);
+ assertEquals("LongitudinalReporting", encoder.getConfig().getAlgorithm());
+ assertEquals(
+ "EncoderId: Foo, ProbabilityF: 0.400, ProbabilityP: 0.250, ProbabilityQ: 1.000",
+ encoder.getConfig().toString());
+ }
+
+ @Test
+ public void testLongitudinalReportingEncoder_basicIRRTest() throws Exception {
+ // Test if IRR can generate expected result when seed is fixed (insecure encoder)
+ final LongitudinalReportingConfig config = new LongitudinalReportingConfig(
+ "Foo", // encoderId
+ 0.4, // probabilityF
+ 0, // probabilityP
+ 0); // probabilityQ
+ // Use insecure encoder here to make sure seed is set.
+ final LongitudinalReportingEncoder encoder =
+ LongitudinalReportingEncoder.createInsecureEncoderForTest(
+ config);
+ assertEquals(1, encoder.encodeBoolean(true)[0]);
+ assertEquals(0, encoder.encodeBoolean(true)[0]);
+ assertEquals(1, encoder.encodeBoolean(true)[0]);
+ assertEquals(1, encoder.encodeBoolean(true)[0]);
+ assertEquals(1, encoder.encodeBoolean(true)[0]);
+ assertEquals(1, encoder.encodeBoolean(true)[0]);
+ assertEquals(0, encoder.encodeBoolean(true)[0]);
+ assertEquals(1, encoder.encodeBoolean(true)[0]);
+ assertEquals(1, encoder.encodeBoolean(true)[0]);
+ assertEquals(1, encoder.encodeBoolean(true)[0]);
+
+ assertEquals(0, encoder.encodeBoolean(false)[0]);
+ assertEquals(1, encoder.encodeBoolean(false)[0]);
+ assertEquals(1, encoder.encodeBoolean(false)[0]);
+ assertEquals(0, encoder.encodeBoolean(false)[0]);
+ assertEquals(0, encoder.encodeBoolean(false)[0]);
+ assertEquals(0, encoder.encodeBoolean(false)[0]);
+ assertEquals(1, encoder.encodeBoolean(false)[0]);
+ assertEquals(0, encoder.encodeBoolean(false)[0]);
+ assertEquals(0, encoder.encodeBoolean(false)[0]);
+ assertEquals(1, encoder.encodeBoolean(false)[0]);
+
+ // Test if IRR returns original result when f = 0
+ final LongitudinalReportingConfig config2 = new LongitudinalReportingConfig(
+ "Foo", // encoderId
+ 0, // probabilityF
+ 0, // probabilityP
+ 0); // probabilityQ
+ final LongitudinalReportingEncoder encoder2
+ = LongitudinalReportingEncoder.createEncoder(
+ config2, makeTestingUserSecret("secret2"));
+ for (int i = 0; i < 10; i++) {
+ assertEquals(1, encoder2.encodeBoolean(true)[0]);
+ }
+ for (int i = 0; i < 10; i++) {
+ assertEquals(0, encoder2.encodeBoolean(false)[0]);
+ }
+
+ // Test if IRR returns opposite result when f = 1
+ final LongitudinalReportingConfig config3 = new LongitudinalReportingConfig(
+ "Foo", // encoderId
+ 1, // probabilityF
+ 0, // probabilityP
+ 0); // probabilityQ
+ final LongitudinalReportingEncoder encoder3
+ = LongitudinalReportingEncoder.createEncoder(
+ config3, makeTestingUserSecret("secret3"));
+ for (int i = 0; i < 10; i++) {
+ assertEquals(1, encoder3.encodeBoolean(false)[0]);
+ }
+ for (int i = 0; i < 10; i++) {
+ assertEquals(0, encoder3.encodeBoolean(true)[0]);
+ }
+ }
+
+ @Test
+ public void testLongitudinalReportingEncoder_basicPRRTest() throws Exception {
+ // Should always return original value when p = 0
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ final LongitudinalReportingConfig config1 = new LongitudinalReportingConfig(
+ "Foo" + i, // encoderId
+ 0, // probabilityF
+ 0, // probabilityP
+ 0); // probabilityQ
+ final LongitudinalReportingEncoder encoder1
+ = LongitudinalReportingEncoder.createEncoder(
+ config1, makeTestingUserSecret("encoder" + j));
+ assertEquals(0, encoder1.encodeBoolean(false)[0]);
+ assertEquals(0, encoder1.encodeBoolean(false)[0]);
+ assertEquals(0, encoder1.encodeBoolean(false)[0]);
+ assertEquals(0, encoder1.encodeBoolean(false)[0]);
+ assertEquals(0, encoder1.encodeBoolean(false)[0]);
+ assertEquals(1, encoder1.encodeBoolean(true)[0]);
+ assertEquals(1, encoder1.encodeBoolean(true)[0]);
+ assertEquals(1, encoder1.encodeBoolean(true)[0]);
+ assertEquals(1, encoder1.encodeBoolean(true)[0]);
+ assertEquals(1, encoder1.encodeBoolean(true)[0]);
+ }
+ }
+
+ // Should always return false when p = 1, q = 0
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ final LongitudinalReportingConfig config2 = new LongitudinalReportingConfig(
+ "Foo" + i, // encoderId
+ 0, // probabilityF
+ 1, // probabilityP
+ 0); // probabilityQ
+ final LongitudinalReportingEncoder encoder2
+ = LongitudinalReportingEncoder.createEncoder(
+ config2, makeTestingUserSecret("encoder" + j));
+ assertEquals(0, encoder2.encodeBoolean(false)[0]);
+ assertEquals(0, encoder2.encodeBoolean(false)[0]);
+ assertEquals(0, encoder2.encodeBoolean(false)[0]);
+ assertEquals(0, encoder2.encodeBoolean(false)[0]);
+ assertEquals(0, encoder2.encodeBoolean(false)[0]);
+ assertEquals(0, encoder2.encodeBoolean(true)[0]);
+ assertEquals(0, encoder2.encodeBoolean(true)[0]);
+ assertEquals(0, encoder2.encodeBoolean(true)[0]);
+ assertEquals(0, encoder2.encodeBoolean(true)[0]);
+ assertEquals(0, encoder2.encodeBoolean(true)[0]);
+ }
+ }
+
+ // Should always return true when p = 1, q = 1
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ final LongitudinalReportingConfig config3 = new LongitudinalReportingConfig(
+ "Foo" + i, // encoderId
+ 0, // probabilityF
+ 1, // probabilityP
+ 1); // probabilityQ
+ final LongitudinalReportingEncoder encoder3
+ = LongitudinalReportingEncoder.createEncoder(
+ config3, makeTestingUserSecret("encoder" + j));
+ assertEquals(1, encoder3.encodeBoolean(false)[0]);
+ assertEquals(1, encoder3.encodeBoolean(false)[0]);
+ assertEquals(1, encoder3.encodeBoolean(false)[0]);
+ assertEquals(1, encoder3.encodeBoolean(false)[0]);
+ assertEquals(1, encoder3.encodeBoolean(false)[0]);
+ assertEquals(1, encoder3.encodeBoolean(true)[0]);
+ assertEquals(1, encoder3.encodeBoolean(true)[0]);
+ assertEquals(1, encoder3.encodeBoolean(true)[0]);
+ assertEquals(1, encoder3.encodeBoolean(true)[0]);
+ assertEquals(1, encoder3.encodeBoolean(true)[0]);
+ }
+ }
+
+ // PRR should return different value when encoder id is changed
+ boolean hasFalseResult1 = false;
+ boolean hasTrueResult1 = false;
+ for (int i = 0; i < 50; i++) {
+ boolean firstResult = false;
+ for (int j = 0; j < 10; j++) {
+ final LongitudinalReportingConfig config4 = new LongitudinalReportingConfig(
+ "Foo" + i, // encoderId
+ 0, // probabilityF
+ 1, // probabilityP
+ 0.5); // probabilityQ
+ final LongitudinalReportingEncoder encoder4
+ = LongitudinalReportingEncoder.createEncoder(
+ config4, makeTestingUserSecret("encoder4"));
+ boolean encodedFalse = encoder4.encodeBoolean(false)[0] > 0;
+ boolean encodedTrue = encoder4.encodeBoolean(true)[0] > 0;
+ // PRR should always give the same value when all parameters are the same
+ assertEquals(encodedTrue, encodedFalse);
+ if (j == 0) {
+ firstResult = encodedTrue;
+ } else {
+ assertEquals(firstResult, encodedTrue);
+ }
+ if (encodedTrue) {
+ hasTrueResult1 = true;
+ } else {
+ hasFalseResult1 = true;
+ }
+ }
+ }
+ // Ensure it has both true and false results when encoder id is different
+ assertTrue(hasTrueResult1);
+ assertTrue(hasFalseResult1);
+
+ // PRR should give different value when secret is changed
+ boolean hasFalseResult2 = false;
+ boolean hasTrueResult2 = false;
+ for (int i = 0; i < 50; i++) {
+ boolean firstResult = false;
+ for (int j = 0; j < 10; j++) {
+ final LongitudinalReportingConfig config5 = new LongitudinalReportingConfig(
+ "Foo", // encoderId
+ 0, // probabilityF
+ 1, // probabilityP
+ 0.5); // probabilityQ
+ final LongitudinalReportingEncoder encoder5
+ = LongitudinalReportingEncoder.createEncoder(
+ config5, makeTestingUserSecret("encoder" + i));
+ boolean encodedFalse = encoder5.encodeBoolean(false)[0] > 0;
+ boolean encodedTrue = encoder5.encodeBoolean(true)[0] > 0;
+ // PRR should always give the same value when parameters are the same
+ assertEquals(encodedTrue, encodedFalse);
+ if (j == 0) {
+ firstResult = encodedTrue;
+ } else {
+ assertEquals(firstResult, encodedTrue);
+ }
+ if (encodedTrue) {
+ hasTrueResult2 = true;
+ } else {
+ hasFalseResult2 = true;
+ }
+ }
+ }
+ // Ensure it has both true and false results when encoder id is different
+ assertTrue(hasTrueResult2);
+ assertTrue(hasFalseResult2);
+
+ // Confirm if PRR randomizer is working correctly
+ final int n1 = 1000;
+ final double p1 = 0.8;
+ final double expectedTrueSum1 = n1 * p1;
+ final double valueRange1 = 5 * Math.sqrt(n1 * p1 * (1 - p1));
+ int trueSum1 = 0;
+ for (int i = 0; i < n1; i++) {
+ final LongitudinalReportingConfig config6 = new LongitudinalReportingConfig(
+ "Foo", // encoderId
+ 0, // probabilityF
+ p1, // probabilityP
+ 1); // probabilityQ
+ final LongitudinalReportingEncoder encoder6
+ = LongitudinalReportingEncoder.createEncoder(
+ config6, makeTestingUserSecret("encoder" + i));
+ boolean encodedFalse = encoder6.encodeBoolean(false)[0] > 0;
+ if (encodedFalse) {
+ trueSum1 += 1;
+ }
+ }
+ // Total number of true(s) should be around the mean (1000 * 0.8)
+ assertTrue(trueSum1 < expectedTrueSum1 + valueRange1);
+ assertTrue(trueSum1 > expectedTrueSum1 - valueRange1);
+
+ // Confirm if PRR randomizer is working correctly
+ final int n2 = 1000;
+ final double p2 = 0.2;
+ final double expectedTrueSum2 = n2 * p2;
+ final double valueRange2 = 5 * Math.sqrt(n2 * p2 * (1 - p2));
+ int trueSum2 = 0;
+ for (int i = 0; i < n2; i++) {
+ final LongitudinalReportingConfig config7 = new LongitudinalReportingConfig(
+ "Foo", // encoderId
+ 0, // probabilityF
+ p2, // probabilityP
+ 1); // probabilityQ
+ final LongitudinalReportingEncoder encoder7
+ = LongitudinalReportingEncoder.createEncoder(
+ config7, makeTestingUserSecret("encoder" + i));
+ boolean encodedFalse = encoder7.encodeBoolean(false)[0] > 0;
+ if (encodedFalse) {
+ trueSum2 += 1;
+ }
+ }
+ // Total number of true(s) should be around the mean (1000 * 0.2)
+ assertTrue(trueSum2 < expectedTrueSum2 + valueRange2);
+ assertTrue(trueSum2 > expectedTrueSum2 - valueRange2);
+ }
+
+ @Test
+ public void testLongitudinalReportingEncoder_basicIRRwithPRRTest() throws Exception {
+ // Verify PRR result will run IRR
+ boolean hasFalseResult1 = false;
+ boolean hasTrueResult1 = false;
+ for (int i = 0; i < 50; i++) {
+ final LongitudinalReportingConfig config1 = new LongitudinalReportingConfig(
+ "Foo", // encoderId
+ 0.5, // probabilityF
+ 1, // probabilityP
+ 1); // probabilityQ
+ final LongitudinalReportingEncoder encoder1
+ = LongitudinalReportingEncoder.createEncoder(
+ config1, makeTestingUserSecret("encoder1"));
+ if (encoder1.encodeBoolean(false)[0] > 0) {
+ hasTrueResult1 = true;
+ } else {
+ hasFalseResult1 = true;
+ }
+ }
+ assertTrue(hasTrueResult1);
+ assertTrue(hasFalseResult1);
+
+ // When secret is different, some device should use PRR result, some should use IRR result
+ boolean hasFalseResult2 = false;
+ boolean hasTrueResult2 = false;
+ for (int i = 0; i < 50; i++) {
+ final LongitudinalReportingConfig config2 = new LongitudinalReportingConfig(
+ "Foo", // encoderId
+ 1, // probabilityF
+ 0.5, // probabilityP
+ 1); // probabilityQ
+ final LongitudinalReportingEncoder encoder2
+ = LongitudinalReportingEncoder.createEncoder(
+ config2, makeTestingUserSecret("encoder" + i));
+ if (encoder2.encodeBoolean(false)[0] > 0) {
+ hasTrueResult2 = true;
+ } else {
+ hasFalseResult2 = true;
+ }
+ }
+ assertTrue(hasTrueResult2);
+ assertTrue(hasFalseResult2);
+ }
+
+ @Test
+ public void testLongTermRandomizedResult() throws Exception {
+ // Verify getLongTermRandomizedResult can return expected result when parameters are fixed.
+ final boolean[] expectedResult =
+ new boolean[]{true, false, true, true, true,
+ false, false, false, true, false,
+ false, false, false, true, true,
+ true, true, false, true, true,
+ true, true, false, true, true};
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 5; j++) {
+ boolean result = LongitudinalReportingEncoder.getLongTermRandomizedResult(0.5,
+ true, makeTestingUserSecret("secret" + i), "encoder" + j);
+ assertEquals(expectedResult[i * 5 + j], result);
+ }
+ }
+ }
+
+ private static byte[] makeTestingUserSecret(String testingSecret) throws Exception {
+ // We generate the fake user secret by concatenating three copies of the
+ // 16 byte MD5 hash of the testingSecret string encoded in UTF 8.
+ MessageDigest md5 = MessageDigest.getInstance("MD5");
+ byte[] digest = md5.digest(testingSecret.getBytes(StandardCharsets.UTF_8));
+ assertEquals(16, digest.length);
+ return ByteBuffer.allocate(48).put(digest).put(digest).put(digest).array();
+ }
+}
diff --git a/core/tests/privacytests/src/android/privacy/RapporEncoderTest.java b/core/tests/privacytests/src/android/privacy/RapporEncoderTest.java
new file mode 100644
index 0000000..dad98b8
--- /dev/null
+++ b/core/tests/privacytests/src/android/privacy/RapporEncoderTest.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.privacy;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.privacy.internal.rappor.RapporConfig;
+import android.privacy.internal.rappor.RapporEncoder;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+
+/**
+ * Unit test for the {@link RapporEncoder}.
+ * Most of the tests are done in external/rappor/client/javatest/ already.
+ * Tests here are just make sure the {@link RapporEncoder} wrap Rappor correctly.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class RapporEncoderTest {
+
+ @Test
+ public void testRapporEncoder_config() throws Exception {
+ final RapporConfig config = new RapporConfig(
+ "Foo", // encoderId
+ 8, // numBits,
+ 13.0 / 128.0, // probabilityF
+ 0.25, // probabilityP
+ 0.75, // probabilityQ
+ 1, // numCohorts
+ 2); // numBloomHashes)
+ final RapporEncoder encoder = RapporEncoder.createEncoder(config,
+ makeTestingUserSecret("encoder1"));
+ assertEquals("Rappor", encoder.getConfig().getAlgorithm());
+ assertEquals("EncoderId: Foo, NumBits: 8, ProbabilityF: 0.102, "
+ + "ProbabilityP: 0.250, ProbabilityQ: 0.750, NumCohorts: 1, "
+ + "NumBloomHashes: 2", encoder.getConfig().toString());
+ }
+
+ @Test
+ public void testRapporEncoder_basicIRRTest() throws Exception {
+ final RapporConfig config = new RapporConfig(
+ "Foo", // encoderId
+ 12, // numBits,
+ 0, // probabilityF
+ 0, // probabilityP
+ 1, // probabilityQ
+ 1, // numCohorts (so must be cohort 0)
+ 2); // numBloomHashes
+ // Use insecure encoder here as we want to get the exact output.
+ final RapporEncoder encoder = RapporEncoder.createInsecureEncoderForTest(config);
+ assertEquals(768, toLong(encoder.encodeString("Testing")));
+ }
+
+ @Test
+ public void testRapporEncoder_IRRWithPRR() throws Exception {
+ int numBits = 8;
+ final long inputValue = 254L;
+ final long prrValue = 250L;
+ final long prrAndIrrValue = 184L;
+
+ final RapporConfig config1 = new RapporConfig(
+ "Foo", // encoderId
+ numBits, // numBits,
+ 0.25, // probabilityF
+ 0, // probabilityP
+ 1, // probabilityQ
+ 1, // numCohorts
+ 2); // numBloomHashes
+ // Use insecure encoder here as we want to get the exact output.
+ final RapporEncoder encoder1 = RapporEncoder.createInsecureEncoderForTest(config1);
+ // Verify that PRR is working as expected.
+ assertEquals(prrValue, toLong(encoder1.encodeBits(toBytes(inputValue))));
+ assertTrue(encoder1.isInsecureEncoderForTest());
+
+ // Verify that IRR is working as expected.
+ final RapporConfig config2 = new RapporConfig(
+ "Foo", // encoderId
+ numBits, // numBits,
+ 0, // probabilityF
+ 0.3, // probabilityP
+ 0.7, // probabilityQ
+ 1, // numCohorts
+ 2); // numBloomHashes
+ // Use insecure encoder here as we want to get the exact output.
+ final RapporEncoder encoder2 = RapporEncoder.createInsecureEncoderForTest(config2);
+ assertEquals(prrAndIrrValue, toLong(encoder2.encodeBits(toBytes(prrValue))));
+
+ // Test that end-to-end is the result of PRR + IRR.
+ final RapporConfig config3 = new RapporConfig(
+ "Foo", // encoderId
+ numBits, // numBits,
+ 0.25, // probabilityF
+ 0.3, // probabilityP
+ 0.7, // probabilityQ
+ 1, // numCohorts
+ 2); // numBloomHashes
+ final RapporEncoder encoder3 = RapporEncoder.createInsecureEncoderForTest(config3);
+ // Verify that PRR is working as expected.
+ assertEquals(prrAndIrrValue, toLong(encoder3.encodeBits(toBytes(inputValue))));
+ }
+
+ @Test
+ public void testRapporEncoder_ensureSecureEncoderIsSecure() throws Exception {
+ int numBits = 8;
+ final long inputValue = 254L;
+ final long prrValue = 250L;
+ final long prrAndIrrValue = 184L;
+
+ final RapporConfig config1 = new RapporConfig(
+ "Foo", // encoderId
+ numBits, // numBits,
+ 0.25, // probabilityF
+ 0, // probabilityP
+ 1, // probabilityQ
+ 1, // numCohorts
+ 2); // numBloomHashes
+ final RapporEncoder encoder1 = RapporEncoder.createEncoder(config1,
+ makeTestingUserSecret("secret1"));
+ // Verify that PRR is working as expected, not affected by random seed.
+ assertEquals(prrValue, toLong(encoder1.encodeBits(toBytes(inputValue))));
+ assertFalse(encoder1.isInsecureEncoderForTest());
+
+ boolean hasDifferentResult2 = false;
+ for (int i = 0; i < 5; i++) {
+ final RapporConfig config2 = new RapporConfig(
+ "Foo", // encoderId
+ numBits, // numBits,
+ 0, // probabilityF
+ 0.3, // probabilityP
+ 0.7, // probabilityQ
+ 1, // numCohorts
+ 2); // numBloomHashes
+ final RapporEncoder encoder2 = RapporEncoder.createEncoder(config2,
+ makeTestingUserSecret("secret1"));
+ hasDifferentResult2 |= (prrAndIrrValue != toLong(
+ encoder2.encodeBits(toBytes(prrValue))));
+ }
+ // Ensure it's not getting same result as it has random seed while encoder id and secret
+ // is the same.
+ assertTrue(hasDifferentResult2);
+
+ boolean hasDifferentResults3 = false;
+ for (int i = 0; i < 5; i++) {
+ final RapporConfig config3 = new RapporConfig(
+ "Foo", // encoderId
+ numBits, // numBits,
+ 0.25, // probabilityF
+ 0.3, // probabilityP
+ 0.7, // probabilityQ
+ 1, // numCohorts
+ 2); // numBloomHashes
+ final RapporEncoder encoder3 = RapporEncoder.createEncoder(config3,
+ makeTestingUserSecret("secret1"));
+ hasDifferentResults3 |= (prrAndIrrValue != toLong(
+ encoder3.encodeBits(toBytes(inputValue))));
+ }
+ // Ensure it's not getting same result as it has random seed while encoder id and secret
+ // is the same.
+ assertTrue(hasDifferentResults3);
+ }
+
+ private static byte[] toBytes(long value) {
+ return ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong(value).array();
+ }
+
+ private static long toLong(byte[] bytes) {
+ ByteBuffer buffer = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).put(bytes);
+ buffer.rewind();
+ return buffer.getLong();
+ }
+
+ private static byte[] makeTestingUserSecret(String testingSecret) throws Exception {
+ // We generate the fake user secret by concatenating three copies of the
+ // 16 byte MD5 hash of the testingSecret string encoded in UTF 8.
+ MessageDigest md5 = MessageDigest.getInstance("MD5");
+ byte[] digest = md5.digest(testingSecret.getBytes(StandardCharsets.UTF_8));
+ assertEquals(16, digest.length);
+ return ByteBuffer.allocate(48).put(digest).put(digest).put(digest).array();
+ }
+}
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index 8c0ca5c..0a9a74e 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -21,7 +21,6 @@
#include "hwui/Typeface.h"
#include "protos/hwui.pb.h"
-#include <../src/sysinfo.h>
#include <benchmark/benchmark.h>
#include <getopt.h>
#include <pthread.h>
@@ -345,9 +344,6 @@
name_field_width += 5;
benchmark::BenchmarkReporter::Context context;
- context.num_cpus = benchmark::NumCPUs();
- context.mhz_per_cpu = benchmark::CyclesPerSecond() / 1000000.0f;
- context.cpu_scaling_enabled = benchmark::CpuScalingEnabled();
context.name_field_width = name_field_width;
gBenchmarkReporter->ReportContext(context);
}
diff --git a/libs/incident/Android.mk b/libs/incident/Android.mk
index 8aa4b10..5f3e407 100644
--- a/libs/incident/Android.mk
+++ b/libs/incident/Android.mk
@@ -31,7 +31,6 @@
LOCAL_SRC_FILES := \
../../core/java/android/os/IIncidentManager.aidl \
- ../../core/java/android/os/IIncidentReportCompletedListener.aidl \
../../core/java/android/os/IIncidentReportStatusListener.aidl \
src/IncidentReportArgs.cpp
diff --git a/packages/InputDevices/res/values-bn/strings.xml b/packages/InputDevices/res/values-bn/strings.xml
index 5f8877a..a61e6ce 100644
--- a/packages/InputDevices/res/values-bn/strings.xml
+++ b/packages/InputDevices/res/values-bn/strings.xml
@@ -42,6 +42,5 @@
<string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"স্প্যানিশ (ল্যাটিন)"</string>
<string name="keyboard_layout_latvian" msgid="4405417142306250595">"লাটভিও"</string>
<string name="keyboard_layout_persian" msgid="3920643161015888527">"ফার্সী"</string>
- <!-- no translation found for keyboard_layout_azerbaijani (7315895417176467567) -->
- <skip />
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"আজারবাইজানি"</string>
</resources>
diff --git a/packages/InputDevices/res/values-gu/strings.xml b/packages/InputDevices/res/values-gu/strings.xml
index d11df01..915f1b6 100644
--- a/packages/InputDevices/res/values-gu/strings.xml
+++ b/packages/InputDevices/res/values-gu/strings.xml
@@ -42,6 +42,5 @@
<string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"સ્પેનિશ (લેટિન)"</string>
<string name="keyboard_layout_latvian" msgid="4405417142306250595">"લાતવિયન"</string>
<string name="keyboard_layout_persian" msgid="3920643161015888527">"પર્શિયન"</string>
- <!-- no translation found for keyboard_layout_azerbaijani (7315895417176467567) -->
- <skip />
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"અઝરબૈજાની"</string>
</resources>
diff --git a/packages/InputDevices/res/values-kn/strings.xml b/packages/InputDevices/res/values-kn/strings.xml
index 2e6f892..8f2b51a 100644
--- a/packages/InputDevices/res/values-kn/strings.xml
+++ b/packages/InputDevices/res/values-kn/strings.xml
@@ -42,6 +42,5 @@
<string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"ಸ್ಪ್ಯಾನಿಶ್ (ಲ್ಯಾಟಿನ್)"</string>
<string name="keyboard_layout_latvian" msgid="4405417142306250595">"ಲ್ಯಾಟ್ವಿಯನ್"</string>
<string name="keyboard_layout_persian" msgid="3920643161015888527">"ಪರ್ಶಿಯನ್"</string>
- <!-- no translation found for keyboard_layout_azerbaijani (7315895417176467567) -->
- <skip />
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"ಅಜೆರ್ಬೈಜಾನಿ"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ml/strings.xml b/packages/InputDevices/res/values-ml/strings.xml
index dfd9754..d346d9f 100644
--- a/packages/InputDevices/res/values-ml/strings.xml
+++ b/packages/InputDevices/res/values-ml/strings.xml
@@ -42,6 +42,5 @@
<string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"സ്പാനിഷ് (ലാറ്റിൻ)"</string>
<string name="keyboard_layout_latvian" msgid="4405417142306250595">"ലാറ്റ്വിയന്"</string>
<string name="keyboard_layout_persian" msgid="3920643161015888527">"പേര്ഷ്യന്"</string>
- <!-- no translation found for keyboard_layout_azerbaijani (7315895417176467567) -->
- <skip />
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"അസര്ബൈജാനി"</string>
</resources>
diff --git a/packages/InputDevices/res/values-pa/strings.xml b/packages/InputDevices/res/values-pa/strings.xml
index 1cf6a2e..f707730 100644
--- a/packages/InputDevices/res/values-pa/strings.xml
+++ b/packages/InputDevices/res/values-pa/strings.xml
@@ -42,6 +42,5 @@
<string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"ਸਪੇਨੀ (ਲਾਤੀਨੀ)"</string>
<string name="keyboard_layout_latvian" msgid="4405417142306250595">"ਲਾਤਵੀਅਨ"</string>
<string name="keyboard_layout_persian" msgid="3920643161015888527">"ਫ਼ਾਰਸੀ"</string>
- <!-- no translation found for keyboard_layout_azerbaijani (7315895417176467567) -->
- <skip />
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"ਅਜ਼ੇਰਬੈਜਾਨੀ"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ta/strings.xml b/packages/InputDevices/res/values-ta/strings.xml
index ebee5c1..a4d07ac 100644
--- a/packages/InputDevices/res/values-ta/strings.xml
+++ b/packages/InputDevices/res/values-ta/strings.xml
@@ -42,6 +42,5 @@
<string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"ஸ்பானிஷ் (லத்தீன்)"</string>
<string name="keyboard_layout_latvian" msgid="4405417142306250595">"லத்வியன்"</string>
<string name="keyboard_layout_persian" msgid="3920643161015888527">"பெர்சியன்"</string>
- <!-- no translation found for keyboard_layout_azerbaijani (7315895417176467567) -->
- <skip />
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"அஜர்பைஜானி"</string>
</resources>
diff --git a/packages/InputDevices/res/values-te/strings.xml b/packages/InputDevices/res/values-te/strings.xml
index 141bb95..f7cce96 100644
--- a/packages/InputDevices/res/values-te/strings.xml
+++ b/packages/InputDevices/res/values-te/strings.xml
@@ -42,6 +42,5 @@
<string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"స్పానిష్ (లాటిన్)"</string>
<string name="keyboard_layout_latvian" msgid="4405417142306250595">"లాత్వియన్"</string>
<string name="keyboard_layout_persian" msgid="3920643161015888527">"పర్షియన్"</string>
- <!-- no translation found for keyboard_layout_azerbaijani (7315895417176467567) -->
- <skip />
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"అజర్బైజాన్"</string>
</resources>
diff --git a/packages/InputDevices/res/values-ur/strings.xml b/packages/InputDevices/res/values-ur/strings.xml
index 71ce1cc..ab95bd5 100644
--- a/packages/InputDevices/res/values-ur/strings.xml
+++ b/packages/InputDevices/res/values-ur/strings.xml
@@ -42,6 +42,5 @@
<string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"ہسپانوی (لاطینی)"</string>
<string name="keyboard_layout_latvian" msgid="4405417142306250595">"لاتویائی"</string>
<string name="keyboard_layout_persian" msgid="3920643161015888527">"فارسی"</string>
- <!-- no translation found for keyboard_layout_azerbaijani (7315895417176467567) -->
- <skip />
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"آزربائیجانی"</string>
</resources>
diff --git a/packages/InputDevices/res/values-uz/strings.xml b/packages/InputDevices/res/values-uz/strings.xml
index e820469..d6f7b2b 100644
--- a/packages/InputDevices/res/values-uz/strings.xml
+++ b/packages/InputDevices/res/values-uz/strings.xml
@@ -42,5 +42,5 @@
<string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Ispan (lotin)"</string>
<string name="keyboard_layout_latvian" msgid="4405417142306250595">"Latish"</string>
<string name="keyboard_layout_persian" msgid="3920643161015888527">"Fors"</string>
- <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"ozarbayjon"</string>
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Ozarbayjon"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 57d1657..22e9d35 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -353,7 +353,7 @@
<string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"Daltonismoa (gorri-berdeak)"</string>
<string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Protanopia (gorri-berdeak)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Tritanopia (urdin-horia)"</string>
- <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kolore-zuzenketa"</string>
+ <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kolorearen zuzenketa"</string>
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Eginbidea esperimentala da eta eragina izan dezake funtzionamenduan."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string>
<string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">^1</xliff:g> inguru gelditzen dira"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index f5cf5f6..47d8408 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -401,7 +401,7 @@
<string name="active_input_method_subtypes" msgid="3596398805424733238">"Métodos de entrada activos"</string>
<string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Usar idiomas do sistema"</string>
<string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Non se puido abrir a configuración de <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
- <string name="ime_security_warning" msgid="4135828934735934248">"É posible que este método de entrada poida recompilar todo o texto que escribas, incluídos os datos persoais como os contrasinais e os números de tarxetas de crédito. Provén da aplicación <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Queres usar este método de entrada?"</string>
+ <string name="ime_security_warning" msgid="4135828934735934248">"Este método de introdución de texto pode recompilar todo o que escribas, incluídos os datos persoais como os contrasinais e os números de tarxetas de crédito. Provén da aplicación <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Queres usar este método de introdución de texto?"</string>
<string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Nota: Tras un reinicio, non se pode iniciar esta aplicación ata que desbloquees o teléfono"</string>
<string name="ims_reg_title" msgid="7609782759207241443">"Estado de rexistro de IMS"</string>
<string name="ims_reg_status_registered" msgid="933003316932739188">"Rexistrado"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index 5df3989..791f5e9 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -135,6 +135,12 @@
<item quantity="other">ডিভাইসটি <xliff:g id="NUMBER_1">%d</xliff:g> ঘন্টা ধরে আনলক করা হয় নি। পাসওয়ার্ড নিশ্চিত করুন।</item>
</plurals>
<string name="fingerprint_not_recognized" msgid="348813995267914625">"স্বীকৃত নয়"</string>
- <!-- no translation found for kg_password_default_pin_message (6203676909479972943) -->
- <!-- no translation found for kg_password_default_puk_message (8744416410184198352) -->
+ <plurals name="kg_password_default_pin_message" formatted="false" msgid="6203676909479972943">
+ <item quantity="one">সিমের পিন লিখুন। আপনি আর <xliff:g id="NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন।</item>
+ <item quantity="other">সিমের পিন লিখুন। আপনি আর <xliff:g id="NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন।</item>
+ </plurals>
+ <plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352">
+ <item quantity="one">সিম অক্ষম করা হয়েছে। চালিয়ে যেতে PUK কোড লিখুন। আপনি আর <xliff:g id="_NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন, তারপরে এই সিমটি আর একেবারেই ব্যবহার করা যাবে না। বিশদে জানতে পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।</item>
+ <item quantity="other">সিম অক্ষম করা হয়েছে। চালিয়ে যেতে PUK কোড লিখুন। আপনি আর <xliff:g id="_NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন, তারপরে এই সিমটি আর একেবারেই ব্যবহার করা যাবে না। বিশদে জানতে পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index a6ee9a6..c62bab8 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -135,6 +135,12 @@
<item quantity="other">ઉપકરણને <xliff:g id="NUMBER_1">%d</xliff:g> કલાક માટે અનલૉક કરવામાં આવ્યું નથી. પાસવર્ડની પુષ્ટિ કરો.</item>
</plurals>
<string name="fingerprint_not_recognized" msgid="348813995267914625">"ઓળખાયેલ નથી"</string>
- <!-- no translation found for kg_password_default_pin_message (6203676909479972943) -->
- <!-- no translation found for kg_password_default_puk_message (8744416410184198352) -->
+ <plurals name="kg_password_default_pin_message" formatted="false" msgid="6203676909479972943">
+ <item quantity="one">સિમ પિન દાખલ કરો, તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
+ <item quantity="other">સિમ પિન દાખલ કરો, તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસો બાકી છે.</item>
+ </plurals>
+ <plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352">
+ <item quantity="one">સિમ હવે બંધ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. સિમ કાયમીરૂપે બિનઉપયોગી બની જાય એ પહેલાં તમારી પાસે <xliff:g id="_NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે. વિગતો માટે કૅરિઅરનો સંપર્ક કરો.</item>
+ <item quantity="other">સિમ હવે બંધ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. સિમ કાયમીરૂપે બિનઉપયોગી બની જાય એ પહેલાં તમારી પાસે <xliff:g id="_NUMBER_1">%d</xliff:g> પ્રયાસો બાકી છે. વિગતો માટે કૅરિઅરનો સંપર્ક કરો.</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index 2ee30e9..2c29112 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -135,6 +135,12 @@
<item quantity="other">ಸಾಧನವನ್ನು <xliff:g id="NUMBER_1">%d</xliff:g> ಗಂಟೆಗಳವರೆಗೆ ಅನ್ಲಾಕ್ ಮಾಡಿರಲಿಲ್ಲ. ಪಾಸ್ವರ್ಡ್ ಖಚಿತಪಡಿಸಿ.</item>
</plurals>
<string name="fingerprint_not_recognized" msgid="348813995267914625">"ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
- <!-- no translation found for kg_password_default_pin_message (6203676909479972943) -->
- <!-- no translation found for kg_password_default_puk_message (8744416410184198352) -->
+ <plurals name="kg_password_default_pin_message" formatted="false" msgid="6203676909479972943">
+ <item quantity="one">ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ, ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ.</item>
+ <item quantity="other">ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ, ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ.</item>
+ </plurals>
+ <plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352">
+ <item quantity="one">ಸಿಮ್ ಅನ್ನು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ಸಿಮ್ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ <xliff:g id="_NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ.</item>
+ <item quantity="other">ಸಿಮ್ ಅನ್ನು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ಸಿಮ್ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ <xliff:g id="_NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ.</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 054ce7c..a4f5b7d 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -141,6 +141,6 @@
</plurals>
<plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352">
<item quantity="other">SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. SIM-картанын биротоло жарактан чыгарына <xliff:g id="_NUMBER_1">%d</xliff:g> аракет калды. Чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз.</item>
- <item quantity="one">SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. SIM-картанын биротоло жарактан чыгарына <xliff:g id="_NUMBER_0">%d</xliff:g> аракет калды. Чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз.</item>
+ <item quantity="one">SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. SIM-картанын биротоло жарактан чыгаарына <xliff:g id="_NUMBER_0">%d</xliff:g> аракет калды. Чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз.</item>
</plurals>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index 7f0e957..d62537d 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -135,6 +135,12 @@
<item quantity="one">ഉപകരണം <xliff:g id="NUMBER_0">%d</xliff:g> മണിക്കൂറായി അൺലോക്ക് ചെയ്തിട്ടില്ല. പാസ്വേഡ് സ്ഥിരീകരിക്കുക.</item>
</plurals>
<string name="fingerprint_not_recognized" msgid="348813995267914625">"തിരിച്ചറിഞ്ഞില്ല"</string>
- <!-- no translation found for kg_password_default_pin_message (6203676909479972943) -->
- <!-- no translation found for kg_password_default_puk_message (8744416410184198352) -->
+ <plurals name="kg_password_default_pin_message" formatted="false" msgid="6203676909479972943">
+ <item quantity="other">സിം പിൻ നൽകുക, <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു.</item>
+ <item quantity="one">സിം പിൻ നൽകുക, ഉപകരണം അൺലോക്ക് ചെയ്യാൻ കാരിയറുമായി ബന്ധപ്പെടേണ്ടിവരുന്നതിന് മുമ്പ് <xliff:g id="NUMBER_0">%d</xliff:g> ശ്രമം കൂടി ശേഷിക്കുന്നു.</item>
+ </plurals>
+ <plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352">
+ <item quantity="other">സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി <xliff:g id="_NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു. വിശദാംശങ്ങൾക്ക് കാരിയറുമായി ബന്ധപ്പെടുക.</item>
+ <item quantity="one">സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി <xliff:g id="_NUMBER_0">%d</xliff:g> ശ്രമം കൂടി ശേഷിക്കുന്നു. വിശദാംശങ്ങൾക്ക് കാരിയറുമായി ബന്ധപ്പെടുക.</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index dc0e53ba..d5d27ca 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -135,6 +135,12 @@
<item quantity="other">ਡੀਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟਿਆਂ ਤੋਂ ਅਣਲਾਕ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ। ਪਾਸਵਰਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ</item>
</plurals>
<string name="fingerprint_not_recognized" msgid="348813995267914625">"ਪਛਾਣ ਨਹੀਂ ਹੋਈ"</string>
- <!-- no translation found for kg_password_default_pin_message (6203676909479972943) -->
- <!-- no translation found for kg_password_default_puk_message (8744416410184198352) -->
+ <plurals name="kg_password_default_pin_message" formatted="false" msgid="6203676909479972943">
+ <item quantity="one">ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।</item>
+ <item quantity="other">ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।</item>
+ </plurals>
+ <plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352">
+ <item quantity="one">ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਸਿਮ ਦੇ ਪੱਕੇ ਤੌਰ \'ਤੇ ਬੇਕਾਰ ਹੋ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="_NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।</item>
+ <item quantity="other">ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਸਿਮ ਦੇ ਪੱਕੇ ਤੌਰ \'ਤੇ ਬੇਕਾਰ ਹੋ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="_NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 727ea5b..2ce57a0 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -135,6 +135,12 @@
<item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> மணிநேரமாகச் சாதனம் திறக்கப்படவில்லை. கடவுச்சொல்லை உறுதிப்படுத்தவும்.</item>
</plurals>
<string name="fingerprint_not_recognized" msgid="348813995267914625">"அடையாளங்காண முடியவில்லை"</string>
- <!-- no translation found for kg_password_default_pin_message (6203676909479972943) -->
- <!-- no translation found for kg_password_default_puk_message (8744416410184198352) -->
+ <plurals name="kg_password_default_pin_message" formatted="false" msgid="6203676909479972943">
+ <item quantity="other">சிம் பின்னை உள்ளிடவும், மேலும் <xliff:g id="NUMBER_1">%d</xliff:g> முறை முயற்சிக்கலாம்.</item>
+ <item quantity="one">சிம் பின்னை உள்ளிடவும், நீங்கள் <xliff:g id="NUMBER_0">%d</xliff:g> முறை மட்டுமே முயற்சிக்க முடியுமென்பதால், அதற்கு முன்பு மொபைல் நிறுவனத்தைத் தொடர்பு கொண்டு சாதனத்தைத் திறக்க முயலவும்.</item>
+ </plurals>
+ <plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352">
+ <item quantity="other">சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு, PUK குறியீட்டை உள்ளிடவும். நீங்கள் <xliff:g id="_NUMBER_1">%d</xliff:g> முறை மட்டுமே முயற்சிக்க முடியும். அதன்பிறகு சிம் நிரந்தரமாக முடக்கப்படும். விவரங்களுக்கு, மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்.</item>
+ <item quantity="one">சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு, PUK குறியீட்டை உள்ளிடவும். நீங்கள் <xliff:g id="_NUMBER_0">%d</xliff:g> முறை மட்டுமே முயற்சிக்க முடியும். அதன்பிறகு சிம் நிரந்தரமாக முடக்கப்படும். விவரங்களுக்கு, மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்.</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index ddc5928..bdee4a3 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -135,6 +135,12 @@
<item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> గంట పాటు పరికరాన్ని అన్లాక్ చేయలేదు. పాస్వర్డ్ని నమోదు చేయండి.</item>
</plurals>
<string name="fingerprint_not_recognized" msgid="348813995267914625">"గుర్తించలేదు"</string>
- <!-- no translation found for kg_password_default_pin_message (6203676909479972943) -->
- <!-- no translation found for kg_password_default_puk_message (8744416410184198352) -->
+ <plurals name="kg_password_default_pin_message" formatted="false" msgid="6203676909479972943">
+ <item quantity="other">SIM పిన్ని నమోదు చేయండి, మీకు <xliff:g id="NUMBER_1">%d</xliff:g> ప్రయత్నలు మిగిలి ఉన్నాయి.</item>
+ <item quantity="one">SIM పిన్ని నమోదు చేయండి, మీరు మీ పరికరాన్ని అన్లాక్ చేయడానికి తప్పనిసరిగా మీ క్యారియర్ను సంప్రదించడానికి ముందు మీకు <xliff:g id="NUMBER_0">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది.</item>
+ </plurals>
+ <plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352">
+ <item quantity="other">SIM ఇప్పుడు నిలిపివేయబడింది. PUK కోడ్ను నమోదు చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="_NUMBER_1">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి. వివరాల కోసం కారియర్ను సంప్రదించండి.</item>
+ <item quantity="one">SIM ఇప్పుడు నిలిపివేయబడింది. PUK కోడ్ను నమోదు చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="_NUMBER_0">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది వివరాల కోసం కారియర్ను సంప్రదించండి.</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 5440a87..cd99c92 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -135,6 +135,12 @@
<item quantity="one">آلہ <xliff:g id="NUMBER_0">%d</xliff:g> گھنٹہ سے غیر مقفل نہیں کیا گیا۔ پاسورڈ کی توثیق کریں۔</item>
</plurals>
<string name="fingerprint_not_recognized" msgid="348813995267914625">"تسلیم شدہ نہیں ہے"</string>
- <!-- no translation found for kg_password_default_pin_message (6203676909479972943) -->
- <!-- no translation found for kg_password_default_puk_message (8744416410184198352) -->
+ <plurals name="kg_password_default_pin_message" formatted="false" msgid="6203676909479972943">
+ <item quantity="other">SIM کا PIN درج کریں، آپ کے پاس <xliff:g id="NUMBER_1">%d</xliff:g> کوششیں بچی ہیں۔</item>
+ <item quantity="one">SIM کا PIN درج کریں، آپ کے پاس <xliff:g id="NUMBER_0">%d</xliff:g> کوشش بچی ہے، اس کے بعد آپ کو اپنا آلہ غیر مقفل کرنے کیلئے اپنے کیریئر سے رابطہ کرنا ہوگا۔</item>
+ </plurals>
+ <plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352">
+ <item quantity="other">SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس <xliff:g id="_NUMBER_1">%d</xliff:g> کوششیں بچی ہیں۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔</item>
+ <item quantity="one">SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس <xliff:g id="_NUMBER_0">%d</xliff:g> کوشش بچی ہے۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index ee11cff..204bb8b 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -140,7 +140,7 @@
<item quantity="one">SIM PIN kodini kiriting, qurilmani qulfdan chiqarish uchun sizda <xliff:g id="NUMBER_0">%d</xliff:g> ta urinish bor.</item>
</plurals>
<plurals name="kg_password_default_puk_message" formatted="false" msgid="8744416410184198352">
- <item quantity="other">SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana <xliff:g id="_NUMBER_1">%d</xliff:g> marta urinib ko‘rganingizdan keyin SIM kartadan umuman foydalanib bo‘lmaydi. Batafsil axborot olish uchun tarmoq operatoriga murojaat qiling.</item>
- <item quantity="one">SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana <xliff:g id="_NUMBER_0">%d</xliff:g> marta urinib ko‘rganingizdan keyin SIM kartadan umuman foydalanib bo‘lmaydi. Batafsil axborot olish uchun tarmoq operatoriga murojaat qiling.</item>
+ <item quantity="other">SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana <xliff:g id="_NUMBER_1">%d</xliff:g> marta xato qilsangiz, SIM kartangiz butunlay qulflanadi. Batafsil axborot olish uchun tarmoq operatoriga murojaat qiling.</item>
+ <item quantity="one">SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana <xliff:g id="_NUMBER_0">%d</xliff:g> marta xato qilsangiz, SIM kartangiz butunlay qulflanadi. Batafsil axborot olish uchun tarmoq operatoriga murojaat qiling.</item>
</plurals>
</resources>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index b9a228f..15a7d4c 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Dubbele multitoonfrekwensie"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Toeganklikheid"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Oproepe"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Lui"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibreer"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Demp"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 961ac45..ee9acae 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"ብሉቱዝ"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"ድርብ ባለ በርካታ ቅላጼ ድግምግሞሽ"</string>
<string name="stream_accessibility" msgid="301136219144385106">"ተደራሽነት"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"ጥሪዎች"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"ጥሪ"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"ንዘር"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"ድምጸ-ከል አድርግ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 8437705..1d8cb4e 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -500,6 +500,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"بلوتوث"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"تردد ثنائي متعدد النغمات"</string>
<string name="stream_accessibility" msgid="301136219144385106">"إمكانية الوصول"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"المكالمات"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"استصدار رنين"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"اهتزاز"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"كتم الصوت"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index ae3854f..fd42eb5 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Višestruka frekvencija dualnog tona"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Pristupačnost"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Pozivi"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Aktiviraj zvono"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibriraj"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Isključi zvuk"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 3c9f83a..e82dbff 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -498,6 +498,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Двухтанальны шматчастотны"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Спецыяльныя магчымасці"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Выклікі"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Званок"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Вібрацыя"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Гук выключаны"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 1cd4c91..ccdc44b 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Тонално набиране"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Достъпност"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Обаждания"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Позвъняване"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Вибриране"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Без звук"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index c823525..96028f7 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -492,12 +492,11 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"ব্লুটুথ"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"ডুয়েল মাল্টি টোন ফ্রিকোয়েন্সি"</string>
<string name="stream_accessibility" msgid="301136219144385106">"অ্যাক্সেসযোগ্যতা"</string>
- <!-- no translation found for volume_ringer_status_normal (4273142424125855384) -->
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
<skip />
- <!-- no translation found for volume_ringer_status_vibrate (1825615171021346557) -->
- <skip />
- <!-- no translation found for volume_ringer_status_silent (6896394161022916369) -->
- <skip />
+ <string name="volume_ringer_status_normal" msgid="4273142424125855384">"রিং"</string>
+ <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"ভাইব্রেট"</string>
+ <string name="volume_ringer_status_silent" msgid="6896394161022916369">"মিউট"</string>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s। সশব্দ করতে আলতো চাপুন।"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s। কম্পন এ সেট করতে আলতো চাপুন। অ্যাক্সেসযোগ্যতার পরিষেবাগুলিকে নিঃশব্দ করা হতে পারে।"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s। নিঃশব্দ করতে আলতো চাপুন। অ্যাক্সেসযোগ্যতার পরিষেবাগুলিকে নিঃশব্দ করা হতে পারে।"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index e87bb45..dacf9d7 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Marcatge per tons"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Accessibilitat"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Trucades"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Fes sonar"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibra"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Silencia"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index e0e14a1..4166697 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -498,6 +498,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Tónová volba"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Přístupnost"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Volání"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Vyzvánění"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibrace"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Ztlumení"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index fb886fc..52446f8 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Tonesignalfrekvens (DTMF)"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Hjælpefunktioner"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Opkald"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Ring"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibration"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Slå lyden fra"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index feb7064..83a8e33 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -496,6 +496,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Doppelton-Mehrfrequenz"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Bedienungshilfen"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Anrufe"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Klingeln lassen"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibrieren"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Stummschalten"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 1fe9010..9a61828 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Πολυσυχνότητα διπλού τόνου"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Προσβασιμότητα"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Κλήσεις"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Κουδούνισμα"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Δόνηση"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Σίγαση"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 4af3f59..d808119 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Multifrecuencia de tono doble"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Accesibilidad"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Llamadas"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Hacer sonar"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibrar"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Silenciar"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 27e4920..3a5af25 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Kaks mitme tooniga sagedust"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Juurdepääsetavus"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Kõned"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Helisemine"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibreerimine"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Vaigistatud"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 5d4181e..87348de 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth konexioa"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Tonu anitzeko maiztasun duala"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Erabilerraztasuna"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Deiak"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Jo tonua"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Dardara"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Ez jo tonua"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 9360c1d..bb77daa 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"بلوتوث"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"فرکانس دوتایی چند نوایی"</string>
<string name="stream_accessibility" msgid="301136219144385106">"دسترسپذیری"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"تماسها"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"زنگ زدن"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"لرزش"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"بیصدا"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 864f8d0..3bebe4b 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Äänitaajuusvalinta"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Esteettömyys"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Puhelut"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Soittoääni"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Värinä"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Äänetön"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 5c4394b..a2dde85 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Fréquence double multi ton"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Accessibilité"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Appels"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Sonnerie"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibration"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Sonnerie désactivée"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index a3d580b..9fbcdec 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -280,7 +280,7 @@
<string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotación bloqueada"</string>
<string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Vertical"</string>
<string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Horizontal"</string>
- <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de entrada"</string>
+ <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de introdución de texto"</string>
<string name="quick_settings_location_label" msgid="5011327048748762257">"Localización"</string>
<string name="quick_settings_location_off_label" msgid="7464544086507331459">"Localización desactivada"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositivo multimedia"</string>
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Multifrecuencia de dobre ton"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Accesibilidade"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Chamadas"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Facer soar"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibrar"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Silenciar"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 83f7896..418f31e1 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -492,12 +492,11 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"બ્લૂટૂથ"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"દ્વિ બહુ ટોન આવર્તન"</string>
<string name="stream_accessibility" msgid="301136219144385106">"ઍક્સેસિબિલિટી"</string>
- <!-- no translation found for volume_ringer_status_normal (4273142424125855384) -->
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
<skip />
- <!-- no translation found for volume_ringer_status_vibrate (1825615171021346557) -->
- <skip />
- <!-- no translation found for volume_ringer_status_silent (6896394161022916369) -->
- <skip />
+ <string name="volume_ringer_status_normal" msgid="4273142424125855384">"રિંગ કરો"</string>
+ <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"વાઇબ્રેટ"</string>
+ <string name="volume_ringer_status_silent" msgid="6896394161022916369">"મ્યૂટ કરો"</string>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. અનમ્યૂટ કરવા માટે ટૅપ કરો."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. વાઇબ્રેટ પર સેટ કરવા માટે ટૅપ કરો. ઍક્સેસિબિલિટી સેવાઓ મ્યૂટ કરવામાં આવી શકે છે."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. મ્યૂટ કરવા માટે ટૅપ કરો. ઍક્સેસિબિલિટી સેવાઓ મ્યૂટ કરવામાં આવી શકે છે."</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index e7fc696..1acd6e7 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -492,6 +492,8 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"ब्लूटूथ"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"दोहरी बहु टोन आवृत्ति"</string>
<string name="stream_accessibility" msgid="301136219144385106">"सुलभता"</string>
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
+ <skip />
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"आवाज़ चालू है"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"कंपन (वाइब्रेशन)"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"आवाज़ बंद है"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 88f5097..7ba9111 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"DTMF"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Pristupačnost"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Pozivi"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Zvonjenje"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibriranje"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Zvuk je isključen"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index e81df8f..8aa2c71 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Kéthangú többfrekvenciás jelzésátvitel (DTMF)"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Kisegítő lehetőségek"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Hívások"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Csörgés"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Rezgés"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Néma"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 2994b9b..2841074 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Կրկնակի բազմերանգ հաճախականություն"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Մատչելիություն"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Զանգեր"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Սովորական"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Թրթռազանգ"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Անձայն"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 1efc249..66530bd 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Tvítóna fjöltíðni"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Aðgengi"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Símtöl"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Hringing"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Titringur"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Hljóð af"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 2927116..cbbffa9 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -496,6 +496,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"טון זוגי מרובה תדרים (DTMF)"</string>
<string name="stream_accessibility" msgid="301136219144385106">"נגישות"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"שיחות"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"צלצול"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"רטט"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"השתקה"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 38622c9..f840225 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"デュアルトーン マルチ周波数"</string>
<string name="stream_accessibility" msgid="301136219144385106">"ユーザー補助機能"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"通話"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"着信音"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"バイブレーション"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"ミュート"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 3f36c72..a9e6ffe 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Қос үнді көп жиілік"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Арнайы мүмкіндіктер"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Қоңыраулар"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Шылдырлау"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Діріл"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Дыбысын өшіру"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 1d5d7d4..5819f2a 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -492,9 +492,10 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"ប៊្លូធូស"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"ហ្វ្រេកង់ពហុសំឡេងទ្វេ"</string>
<string name="stream_accessibility" msgid="301136219144385106">"ភាពងាយស្រួល"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"ហៅទូរសព្ទ"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"រោទ៍"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"ញ័រ"</string>
- <string name="volume_ringer_status_silent" msgid="6896394161022916369">"បិទ"</string>
+ <string name="volume_ringer_status_silent" msgid="6896394161022916369">"បិទសំឡេង"</string>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s។ ប៉ះដើម្បីបើកសំឡេង។"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s។ ប៉ះដើម្បីកំណត់ឲ្យញ័រ។ សេវាកម្មលទ្ធភាពប្រើប្រាស់អាចនឹងត្រូវបានបិទសំឡេង។"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s។ ប៉ះដើម្បីបិទសំឡេង។ សេវាកម្មលទ្ធភាពប្រើប្រាស់អាចនឹងត្រូវបានបិទសំឡេង។"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index b2e9d8f..5e7e1e2 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -492,12 +492,11 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"ಬ್ಲೂಟೂತ್"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"ಡ್ಯುಯಲ್ ಬಹು ಟೋನ್ ಆವರ್ತನೆ"</string>
<string name="stream_accessibility" msgid="301136219144385106">"ಪ್ರವೇಶಿಸುವಿಕೆ"</string>
- <!-- no translation found for volume_ringer_status_normal (4273142424125855384) -->
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
<skip />
- <!-- no translation found for volume_ringer_status_vibrate (1825615171021346557) -->
- <skip />
- <!-- no translation found for volume_ringer_status_silent (6896394161022916369) -->
- <skip />
+ <string name="volume_ringer_status_normal" msgid="4273142424125855384">"ರಿಂಗ್"</string>
+ <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"ವೈಬ್ರೇಟ್"</string>
+ <string name="volume_ringer_status_silent" msgid="6896394161022916369">"ಮ್ಯೂಟ್"</string>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. ಅನ್ಮ್ಯೂಟ್ ಮಾಡುವುದಕ್ಕಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. ಕಂಪನಕ್ಕೆ ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಪ್ರವೇಶಿಸುವಿಕೆ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಬಹುದು."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಪ್ರವೇಶಿಸುವಿಕೆ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಬಹುದು."</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 83018be..d86c32f 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"블루투스"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"듀얼 멀티 톤 주파수"</string>
<string name="stream_accessibility" msgid="301136219144385106">"접근성"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"통화"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"벨소리"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"진동"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"음소거"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 4aaae3c..e10e2b0 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Көп тондуу жыштык"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Атайын мүмкүнчүлүктөр"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Чалуулар"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Шыңгыратуу"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Дирилдөө"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Үнсүз"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index bc1e5b9..2587a20 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"ບຣູທູດ"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Dual multi tone frequency"</string>
<string name="stream_accessibility" msgid="301136219144385106">"ການຊ່ວຍເຂົ້າເຖິງ"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"ການໂທ"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"ເຕືອນດ້ວຍສຽງ"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"ສັ່ນເຕືອນ"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"ປິດ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 53ddcb3..1c97452 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -496,6 +496,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Dvigubas kelių tonų dažnis"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Pritaikymas neįgaliesiems"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Skambučiai"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Skambinti"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibruoti"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Nutildyti"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index b1c3db5..c14eb3f 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Divtoņu daudzfrekvenču signalizācija"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Pieejamība"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Zvani"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Zvanīt"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibrēt"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Izslēgt skaņu"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 3986e16..e30085c 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Двојна повеќетонска фреквенција"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Пристапност"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Повици"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Ѕвони"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Вибрации"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Исклучи звук"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 3dfde13..385331e 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -492,12 +492,11 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"ബ്ലൂടൂത്ത്"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"ഡ്യുവൽ മൾട്ടി റ്റോൺ ഫ്രീക്വൻസി"</string>
<string name="stream_accessibility" msgid="301136219144385106">"ഉപയോഗസഹായി"</string>
- <!-- no translation found for volume_ringer_status_normal (4273142424125855384) -->
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
<skip />
- <!-- no translation found for volume_ringer_status_vibrate (1825615171021346557) -->
- <skip />
- <!-- no translation found for volume_ringer_status_silent (6896394161022916369) -->
- <skip />
+ <string name="volume_ringer_status_normal" msgid="4273142424125855384">"റിംഗ് ചെയ്യുക"</string>
+ <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"വൈബ്രേറ്റ് ചെയ്യുക"</string>
+ <string name="volume_ringer_status_silent" msgid="6896394161022916369">"മ്യൂട്ട് ചെയ്യുക"</string>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. അൺമ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. വൈബ്രേറ്റിലേക്ക് സജ്ജമാക്കുന്നതിന് ടാപ്പുചെയ്യുക. ഉപയോഗസഹായി സേവനങ്ങൾ മ്യൂട്ടുചെയ്യപ്പെട്ടേക്കാം."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. മ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക. ഉപയോഗസഹായി സേവനങ്ങൾ മ്യൂട്ടുചെയ്യപ്പെട്ടേക്കാം."</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 9f09dad..480956c 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -490,6 +490,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Олон дууны давтамж"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Хүртээмж"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Дуудлага"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Хонх дуугаргах"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Чичиргэх"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Хаах"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 5b0984d..8a0d661 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -492,6 +492,8 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"ब्लूटूथ"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"दुहेरी एकाधिक टोन वारंंवारता"</string>
<string name="stream_accessibility" msgid="301136219144385106">"प्रवेशयोग्यता"</string>
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
+ <skip />
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"रिंग करा"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"कंपन"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"म्युट करा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 2907761..e074875 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Multifrekuensi dwinada"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Kebolehaksesan"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Panggilan"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Dering"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Getar"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Redam"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 51b3b0d..661df03 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"DTMF (dual-tone multi-frequency)"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Tilgjengelighet"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Anrop"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Ring"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibrer"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Ignorer"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 0a63ce2..dce9cc4 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -492,6 +492,8 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"ब्लुटुथ"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"दोहोरो बहु टोनको फ्रिक्वेन्सी"</string>
<string name="stream_accessibility" msgid="301136219144385106">"पहुँच"</string>
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
+ <skip />
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"घन्टी"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"कम्पन"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"म्युट गर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index c6475dc..43503d6 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -492,12 +492,11 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"ਬਲੂਟੁੱਥ"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"ਦੂਹਰੀ ਮਲਟੀ ਟੋਨ ਆਵਰਤੀ"</string>
<string name="stream_accessibility" msgid="301136219144385106">"ਪਹੁੰਚਯੋਗਤਾ"</string>
- <!-- no translation found for volume_ringer_status_normal (4273142424125855384) -->
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
<skip />
- <!-- no translation found for volume_ringer_status_vibrate (1825615171021346557) -->
- <skip />
- <!-- no translation found for volume_ringer_status_silent (6896394161022916369) -->
- <skip />
+ <string name="volume_ringer_status_normal" msgid="4273142424125855384">"ਘੰਟੀ"</string>
+ <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"ਥਰਥਰਾਹਟ"</string>
+ <string name="volume_ringer_status_silent" msgid="6896394161022916369">"ਮਿਊਟ"</string>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s। ਅਣਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s। ਥਰਥਰਾਹਟ ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਮਿਊਟ ਹੋ ਸਕਦੀਆਂ ਹਨ।"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਮਿਊਟ ਹੋ ਸਕਦੀਆਂ ਹਨ।"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index bc2a954..e567e6ba 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -496,6 +496,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"DTMF"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Ułatwienia dostępu"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Połączenia"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Dzwonek"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Wibracje"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Wyciszenie"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 7f2c643..681d3e4 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Multifrequência de duas tonalidades"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Acessibilidade"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Chamadas"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Toque"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibrar"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Desativar som"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 2108455..2a0744e 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -496,6 +496,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Frecvență tonuri multiple duale"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Accesibilitate"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Apeluri"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Sonerie"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibrații"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Blocați"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 151c2b4..694695c 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -498,6 +498,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Dvojtónová multifrekvencia"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Dostupnosť"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Hovory"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Prezvoniť"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibrovať"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Vypnúť zvuk"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index ee628e1..10d0104 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -498,6 +498,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Dvojna večtonska frekvenca"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Funkcije za ljudi s posebnimi potrebami"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Klici"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Zvonjenje"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibriranje"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Utišano"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 7641e6c..665177f 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Frekuenca e dyfishtë me shumë tone"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Qasshmëria"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Telefonatat"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Bjeri ziles"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Dridhje"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Pa zë"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index b5fab0d..cef0f693 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Вишеструка фреквенција дуалног тона"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Приступачност"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Позиви"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Активирај звоно"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Вибрирај"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Искључи звук"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index cc6f542..c8f8db4 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Tonval"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Tillgänglighet"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Samtal"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Ringsignal"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibration"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Dölj"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index b83f10f..8fa370d 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Masafa ya ishara ya kampuni ya simu"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Zana za walio na matatizo ya kuona au kusikia"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Simu"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Piga"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Tetema"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Zima sauti"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 9d532e2..6568381 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -492,12 +492,11 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"புளூடூத்"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"டூயல் டோன் மல்டி ஃப்ரீக்வென்சி"</string>
<string name="stream_accessibility" msgid="301136219144385106">"அணுகல்தன்மை"</string>
- <!-- no translation found for volume_ringer_status_normal (4273142424125855384) -->
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
<skip />
- <!-- no translation found for volume_ringer_status_vibrate (1825615171021346557) -->
- <skip />
- <!-- no translation found for volume_ringer_status_silent (6896394161022916369) -->
- <skip />
+ <string name="volume_ringer_status_normal" msgid="4273142424125855384">"ஒலி"</string>
+ <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"அதிர்வு"</string>
+ <string name="volume_ringer_status_silent" msgid="6896394161022916369">"அமைதி"</string>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. ஒலி இயக்க, தட்டவும்."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. அதிர்விற்கு அமைக்க, தட்டவும். அணுகல்தன்மை சேவைகள் ஒலியடக்கப்படக்கூடும்."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. ஒலியடக்க, தட்டவும். அணுகல்தன்மை சேவைகள் ஒலியடக்கப்படக்கூடும்."</string>
@@ -762,7 +761,7 @@
<string name="instant_apps" msgid="6647570248119804907">"இன்ஸ்டண்ட் பயன்பாடுகள்"</string>
<string name="instant_apps_message" msgid="8116608994995104836">"இன்ஸ்டண்ட் பயன்பாடுகளுக்கு நிறுவல் தேவையில்லை."</string>
<string name="app_info" msgid="6856026610594615344">"ஆப்ஸ் தகவல்"</string>
- <string name="go_to_web" msgid="2650669128861626071">"உலாவிக்குக்குச் செல்"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"உலாவிக்குச் செல்"</string>
<string name="mobile_data" msgid="7094582042819250762">"மொபைல் டேட்டா"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"வைஃபை முடக்கத்தில் உள்ளது"</string>
<string name="bt_is_off" msgid="2640685272289706392">"புளூடூத் முடக்கத்தில் உள்ளது"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index f1c66f5..fa7cb09 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -492,12 +492,11 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"బ్లూటూత్"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"డ్యూయల్ మల్టీ టోన్ ఫ్రీక్వెన్సీ"</string>
<string name="stream_accessibility" msgid="301136219144385106">"యాక్సెస్ సామర్థ్యం"</string>
- <!-- no translation found for volume_ringer_status_normal (4273142424125855384) -->
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
<skip />
- <!-- no translation found for volume_ringer_status_vibrate (1825615171021346557) -->
- <skip />
- <!-- no translation found for volume_ringer_status_silent (6896394161022916369) -->
- <skip />
+ <string name="volume_ringer_status_normal" msgid="4273142424125855384">"రింగ్"</string>
+ <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"వైబ్రేట్"</string>
+ <string name="volume_ringer_status_silent" msgid="6896394161022916369">"మ్యూట్"</string>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. అన్మ్యూట్ చేయడానికి నొక్కండి."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. వైబ్రేషన్కు సెట్ చేయడానికి నొక్కండి. యాక్సెస్ సామర్థ్య సేవలు మ్యూట్ చేయబడవచ్చు."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. మ్యూట్ చేయడానికి నొక్కండి. యాక్సెస్ సామర్థ్య సేవలు మ్యూట్ చేయబడవచ్చు."</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index ea61018..d43efdd 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"บลูทูธ"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"การส่งสัญญาณเสียงแบบ 2 เสียงพร้อมกัน"</string>
<string name="stream_accessibility" msgid="301136219144385106">"การเข้าถึง"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"การโทร"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"ทำให้ส่งเสียง"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"สั่น"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"ปิดเสียง"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index cdf28d6..4aa9ca4 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Dual multi tone frequency"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Pagiging Naa-access"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Mga Tawag"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Ipa-ring"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"I-vibrate"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"I-mute"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 5dc81a1..d028fdd 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Çift ton çoklu frekans"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Erişilebilirlik"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Çağrılar"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Zili çaldır"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Titreşim"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Sesi kapat"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 6498088..73fd5886 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -492,12 +492,11 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"بلوٹوتھ"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"دوہری ملٹی ٹون فریکوئنسی"</string>
<string name="stream_accessibility" msgid="301136219144385106">"ایکسیسبیلٹی"</string>
- <!-- no translation found for volume_ringer_status_normal (4273142424125855384) -->
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
<skip />
- <!-- no translation found for volume_ringer_status_vibrate (1825615171021346557) -->
- <skip />
- <!-- no translation found for volume_ringer_status_silent (6896394161022916369) -->
- <skip />
+ <string name="volume_ringer_status_normal" msgid="4273142424125855384">"رِنگ کریں"</string>
+ <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"وائبریٹ"</string>
+ <string name="volume_ringer_status_silent" msgid="6896394161022916369">"خاموش کریں"</string>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s۔ آواز چالو کرنے کیلئے تھپتھپائیں۔"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s۔ ارتعاش پر سیٹ کرنے کیلئے تھپتھپائیں۔ ایکسیسبیلٹی سروسز شاید خاموش ہوں۔"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s۔ خاموش کرنے کیلئے تھپتھپائیں۔ ایکسیسبیلٹی سروسز شاید خاموش ہوں۔"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 273079d..55eb4fb 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Ikkitali ko‘pchastotali ovoz"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Maxsus imkoniyatlar"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Chaqiruvlar"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Jiringlatish"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Tebranish"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Ovozsiz"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index df06298..551decf 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"Tần số đa chuông kép"</string>
<string name="stream_accessibility" msgid="301136219144385106">"Trợ năng"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"Cuộc gọi"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"Đổ chuông"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Rung"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"Tắt tiếng"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index f7999a6..2b64d86 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -492,6 +492,8 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"蓝牙"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"双音多频"</string>
<string name="stream_accessibility" msgid="301136219144385106">"无障碍"</string>
+ <!-- no translation found for ring_toggle_title (3281244519428819576) -->
+ <skip />
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"响铃"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"振动"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"静音"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 188ad7c..382425d 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -494,6 +494,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"藍牙"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"雙音多頻訊號"</string>
<string name="stream_accessibility" msgid="301136219144385106">"無障礙功能"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"通話"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"鈴聲"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"震動"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"靜音"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 75f8015..ef9ea43 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -492,6 +492,7 @@
<string name="stream_bluetooth_sco" msgid="2055645746402746292">"藍牙"</string>
<string name="stream_dtmf" msgid="2447177903892477915">"雙音多頻"</string>
<string name="stream_accessibility" msgid="301136219144385106">"協助工具"</string>
+ <string name="ring_toggle_title" msgid="3281244519428819576">"通話"</string>
<string name="volume_ringer_status_normal" msgid="4273142424125855384">"鈴聲"</string>
<string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"震動"</string>
<string name="volume_ringer_status_silent" msgid="6896394161022916369">"靜音"</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index d58b69d..2058f15 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -71,6 +71,7 @@
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.IccCardConstants.State;
import com.android.internal.telephony.PhoneConstants;
@@ -1111,7 +1112,8 @@
}
}
- private KeyguardUpdateMonitor(Context context) {
+ @VisibleForTesting
+ protected KeyguardUpdateMonitor(Context context) {
mContext = context;
mSubscriptionManager = SubscriptionManager.from(context);
mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index e80d6d3..3177c03 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -16,6 +16,7 @@
package com.android.systemui;
+import android.app.AlarmManager;
import android.content.Context;
import android.util.ArrayMap;
import android.util.Log;
@@ -92,10 +93,10 @@
public ScrimController createScrimController(LightBarController lightBarController,
ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
- LockscreenWallpaper lockscreenWallpaper, Consumer<Boolean> scrimVisibleListener,
- DozeParameters dozeParameters) {
+ LockscreenWallpaper lockscreenWallpaper, Consumer<Integer> scrimVisibleListener,
+ DozeParameters dozeParameters, AlarmManager alarmManager) {
return new ScrimController(lightBarController, scrimBehind, scrimInFront, headsUpScrim,
- scrimVisibleListener, dozeParameters);
+ scrimVisibleListener, dozeParameters, alarmManager);
}
public NotificationIconAreaController createNotificationIconAreaController(Context context,
diff --git a/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java b/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java
index cc2244a..8515bf2 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java
@@ -40,12 +40,16 @@
private static final long DEFAULT_PROX_SCREEN_OFF_DELAY_MS = 10 * DateUtils.SECOND_IN_MILLIS;
private static final long DEFAULT_PROX_COOLDOWN_TRIGGER_MS = 2 * DateUtils.SECOND_IN_MILLIS;
private static final long DEFAULT_PROX_COOLDOWN_PERIOD_MS = 5 * DateUtils.SECOND_IN_MILLIS;
+ private static final long DEFAULT_WALLPAPER_VISIBILITY_MS = 60 * DateUtils.SECOND_IN_MILLIS;
+ private static final long DEFAULT_WALLPAPER_FADE_OUT_MS = 400;
static final String KEY_SCREEN_BRIGHTNESS_ARRAY = "screen_brightness_array";
static final String KEY_DIMMING_SCRIM_ARRAY = "dimming_scrim_array";
static final String KEY_PROX_SCREEN_OFF_DELAY_MS = "prox_screen_off_delay";
static final String KEY_PROX_COOLDOWN_TRIGGER_MS = "prox_cooldown_trigger";
static final String KEY_PROX_COOLDOWN_PERIOD_MS = "prox_cooldown_period";
+ static final String KEY_WALLPAPER_VISIBILITY_MS = "wallpaper_visibility_timeout";
+ static final String KEY_WALLPAPER_FADE_OUT_MS = "wallpaper_fade_out_duration";
/**
* Integer array to map ambient brightness type to real screen brightness.
@@ -89,6 +93,24 @@
*/
public long proxCooldownPeriodMs;
+ /**
+ * For how long(ms) the wallpaper should still be visible
+ * after entering AoD.
+ *
+ * @see Settings.Global#ALWAYS_ON_DISPLAY_CONSTANTS
+ * @see #KEY_WALLPAPER_VISIBILITY_MS
+ */
+ public long wallpaperVisibilityDuration;
+
+ /**
+ * Duration(ms) of the fade out animation after
+ * {@link #KEY_WALLPAPER_VISIBILITY_MS} elapses.
+ *
+ * @see Settings.Global#ALWAYS_ON_DISPLAY_CONSTANTS
+ * @see #KEY_WALLPAPER_FADE_OUT_MS
+ */
+ public long wallpaperFadeOutDuration;
+
private final KeyValueListParser mParser;
private final Context mContext;
private SettingsObserver mSettingsObserver;
@@ -138,6 +160,10 @@
DEFAULT_PROX_COOLDOWN_TRIGGER_MS);
proxCooldownPeriodMs = mParser.getLong(KEY_PROX_COOLDOWN_PERIOD_MS,
DEFAULT_PROX_COOLDOWN_PERIOD_MS);
+ wallpaperFadeOutDuration = mParser.getLong(KEY_WALLPAPER_FADE_OUT_MS,
+ DEFAULT_WALLPAPER_FADE_OUT_MS);
+ wallpaperVisibilityDuration = mParser.getLong(KEY_WALLPAPER_VISIBILITY_MS,
+ DEFAULT_WALLPAPER_VISIBILITY_MS);
screenBrightnessArray = mParser.getIntArray(KEY_SCREEN_BRIGHTNESS_ARRAY,
resources.getIntArray(
R.array.config_doze_brightness_sensor_to_brightness));
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index a409fcb..0f0402d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -66,6 +66,7 @@
createDozeUi(context, host, wakeLock, machine, handler, alarmManager, params),
new DozeScreenState(wrappedService, handler),
createDozeScreenBrightness(context, wrappedService, sensorManager, host, handler),
+ new DozeWallpaperState()
});
return machine;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 6650cc6..34d3928 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -24,9 +24,10 @@
import com.android.systemui.Dependency;
import com.android.systemui.plugins.DozeServicePlugin;
-import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.DozeServicePlugin.RequestDoze;
import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
new file mode 100644
index 0000000..50c1ede
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.doze;
+
+import android.app.IWallpaperManager;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+
+/**
+ * Propagates doze state to wallpaper engine.
+ */
+public class DozeWallpaperState implements DozeMachine.Part {
+
+ private static final String TAG = "DozeWallpaperState";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ @VisibleForTesting
+ final IWallpaperManager mWallpaperManagerService;
+ private boolean mIsAmbientMode;
+
+ public DozeWallpaperState() {
+ this(IWallpaperManager.Stub.asInterface(
+ ServiceManager.getService(Context.WALLPAPER_SERVICE)));
+ }
+
+ @VisibleForTesting
+ DozeWallpaperState(IWallpaperManager wallpaperManagerService) {
+ mWallpaperManagerService = wallpaperManagerService;
+ }
+
+ @Override
+ public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+ final boolean isAmbientMode;
+ switch (newState) {
+ case DOZE_AOD:
+ case DOZE_REQUEST_PULSE:
+ case DOZE_PULSING:
+ case DOZE_PULSE_DONE:
+ isAmbientMode = true;
+ break;
+ default:
+ isAmbientMode = false;
+ }
+
+ if (isAmbientMode != mIsAmbientMode) {
+ mIsAmbientMode = isAmbientMode;
+ try {
+ Log.i(TAG, "AoD wallpaper state changed to: " + mIsAmbientMode);
+ mWallpaperManagerService.setInAmbientMode(mIsAmbientMode);
+ } catch (RemoteException e) {
+ // Cannot notify wallpaper manager service, but it's fine, let's just skip it.
+ Log.w(TAG, "Cannot notify state to WallpaperManagerService: " + mIsAmbientMode);
+ }
+ }
+ }
+
+ @Override
+ public void dump(PrintWriter pw) {
+ pw.println("DozeWallpaperState:");
+ pw.println(" isAmbientMode: " + mIsAmbientMode);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 50cbd69..6d85fb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -26,6 +26,7 @@
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.systemui.R;
+import com.android.systemui.doze.AlwaysOnDisplayPolicy;
import java.io.PrintWriter;
@@ -37,10 +38,12 @@
private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
private static IntInOutMatcher sPickupSubtypePerformsProxMatcher;
+ private final AlwaysOnDisplayPolicy mAlwaysOnPolicy;
public DozeParameters(Context context) {
mContext = context;
mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
+ mAlwaysOnPolicy = new AlwaysOnDisplayPolicy(context);
}
public void dump(PrintWriter pw) {
@@ -83,6 +86,11 @@
return getPulseInDuration() + getPulseVisibleDuration() + getPulseOutDuration();
}
+ public float getScreenBrightnessDoze() {
+ return mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_screenBrightnessDoze) / 255f;
+ }
+
public int getPulseInDuration() {
return getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
}
@@ -115,6 +123,26 @@
return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
}
+ /**
+ * For how long a wallpaper can be visible in AoD before it fades aways.
+ * @return duration in millis.
+ */
+ public long getWallpaperAodDuration() {
+ return mAlwaysOnPolicy.wallpaperVisibilityDuration;
+ }
+
+ /**
+ * How long it takes for the wallpaper fade away (Animation duration.)
+ * @return duration in millis.
+ */
+ public long getWallpaperFadeOutDuration() {
+ return mAlwaysOnPolicy.wallpaperFadeOutDuration;
+ }
+
+ /**
+ * Checks if always on is available and enabled for the current user.
+ * @return {@code true} if enabled and available.
+ */
public boolean getAlwaysOn() {
return mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
}
@@ -123,7 +151,7 @@
* Some screens need to be completely black before changing the display power mode,
* unexpected behavior might happen if this parameter isn't respected.
*
- * @return true if screen needs to be completely black before a power transition.
+ * @return {@code true} if screen needs to be completely black before a power transition.
*/
public boolean getDisplayNeedsBlanking() {
return mContext.getResources().getBoolean(
@@ -134,7 +162,7 @@
* Whether we can implement our own screen off animation or if we need
* to rely on DisplayPowerManager to dim the display.
*
- * @return true if SystemUI can control the screen off animation.
+ * @return {@code true} if SystemUI can control the screen off animation.
*/
public boolean getCanControlScreenOffAnimation() {
return !mContext.getResources().getBoolean(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 168758f..14329b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -20,6 +20,7 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
+import android.app.AlarmManager;
import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Color;
@@ -51,6 +52,7 @@
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.stack.ViewState;
+import com.android.systemui.util.AlarmTimeout;
import com.android.systemui.util.wakelock.DelayedWakeLock;
import com.android.systemui.util.wakelock.WakeLock;
@@ -73,6 +75,19 @@
= new PathInterpolator(0f, 0, 0.7f, 1f);
public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR_LOCKED
= new PathInterpolator(0.3f, 0f, 0.8f, 1f);
+
+ /**
+ * When both scrims have 0 alpha.
+ */
+ public static final int VISIBILITY_FULLY_TRANSPARENT = 0;
+ /**
+ * When scrims aren't transparent (alpha 0) but also not opaque (alpha 1.)
+ */
+ public static final int VISIBILITY_SEMI_TRANSPARENT = 1;
+ /**
+ * When at least 1 scrim is fully opaque (alpha set to 1.)
+ */
+ public static final int VISIBILITY_FULLY_OPAQUE = 2;
/**
* Default alpha value for most scrims.
*/
@@ -111,6 +126,7 @@
private final UnlockMethodCache mUnlockMethodCache;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final DozeParameters mDozeParameters;
+ private final AlarmTimeout mTimeTicker;
private final SysuiColorExtractor mColorExtractor;
private GradientColors mLockColors;
@@ -138,23 +154,25 @@
private float mCurrentBehindAlpha = NOT_INITIALIZED;
private int mCurrentInFrontTint;
private int mCurrentBehindTint;
+ private boolean mWallpaperVisibilityTimedOut;
private int mPinnedHeadsUpCount;
private float mTopHeadsUpDragAmount;
private View mDraggedHeadsUpView;
private boolean mKeyguardFadingOutInProgress;
private ValueAnimator mKeyguardFadeoutAnimation;
- private boolean mScrimsVisible;
- private final Consumer<Boolean> mScrimVisibleListener;
+ private int mScrimsVisibility;
+ private final Consumer<Integer> mScrimVisibleListener;
private boolean mBlankScreen;
private boolean mScreenBlankingCallbackCalled;
private Callback mCallback;
+ private boolean mWallpaperSupportsAmbientMode;
private final WakeLock mWakeLock;
private boolean mWakeLockHeld;
public ScrimController(LightBarController lightBarController, ScrimView scrimBehind,
- ScrimView scrimInFront, View headsUpScrim, Consumer<Boolean> scrimVisibleListener,
- DozeParameters dozeParameters) {
+ ScrimView scrimInFront, View headsUpScrim, Consumer<Integer> scrimVisibleListener,
+ DozeParameters dozeParameters, AlarmManager alarmManager) {
mScrimBehind = scrimBehind;
mScrimInFront = scrimInFront;
mHeadsUpScrim = headsUpScrim;
@@ -164,6 +182,8 @@
mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
mLightBarController = lightBarController;
mScrimBehindAlphaResValue = mContext.getResources().getFloat(R.dimen.scrim_behind_alpha);
+ mTimeTicker = new AlarmTimeout(alarmManager, this::onHideWallpaperTimeout,
+ "hide_aod_wallpaper", new Handler());
mWakeLock = createWakeLock();
// Scrim alpha is initially set to the value on the resource but might be changed
// to make sure that text on top of it is legible.
@@ -235,14 +255,24 @@
mKeyguardFadeoutAnimation.cancel();
}
- // Do not let the device sleep until we're done with all animations
- if (!mWakeLockHeld) {
- if (mWakeLock != null) {
- mWakeLockHeld = true;
- mWakeLock.acquire();
- } else {
- Log.w(TAG, "Cannot hold wake lock, it has not been set yet");
+ // The device might sleep if it's entering AOD, we need to make sure that
+ // the animation plays properly until the last frame.
+ // It's important to avoid holding the wakelock unless necessary because
+ // WakeLock#aqcuire will trigger an IPC and will cause jank.
+ if (mState == ScrimState.AOD) {
+ holdWakeLock();
+ }
+
+ // AOD wallpapers should fade away after a while
+ if (mWallpaperSupportsAmbientMode && mDozeParameters.getAlwaysOn()
+ && (mState == ScrimState.AOD || mState == ScrimState.PULSING)) {
+ if (!mWallpaperVisibilityTimedOut) {
+ mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
+ AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
}
+ } else {
+ mTimeTicker.cancel();
+ mWallpaperVisibilityTimedOut = false;
}
if (!mKeyguardUpdateMonitor.needsSlowUnlockTransition()) {
@@ -279,6 +309,30 @@
mTracking = false;
}
+ @VisibleForTesting
+ protected void onHideWallpaperTimeout() {
+ if (mState != ScrimState.AOD && mState != ScrimState.PULSING) {
+ return;
+ }
+
+ holdWakeLock();
+ mWallpaperVisibilityTimedOut = true;
+ mAnimateChange = true;
+ mAnimationDuration = mDozeParameters.getWallpaperFadeOutDuration();
+ scheduleUpdate();
+ }
+
+ private void holdWakeLock() {
+ if (!mWakeLockHeld) {
+ if (mWakeLock != null) {
+ mWakeLockHeld = true;
+ mWakeLock.acquire();
+ } else {
+ Log.w(TAG, "Cannot hold wake lock, it has not been set yet");
+ }
+ }
+ }
+
/**
* Current state of the shade expansion when pulling it from the top.
* This value is 1 when on top of the keyguard and goes to 0 as the user drags up.
@@ -391,6 +445,14 @@
mLightBarController.setScrimColor(mScrimInFront.getColors());
}
+ // We want to override the back scrim opacity for AOD and PULSING
+ // when it's time to fade the wallpaper away.
+ boolean overrideBackScrimAlpha = (mState == ScrimState.PULSING || mState == ScrimState.AOD)
+ && mWallpaperVisibilityTimedOut;
+ if (overrideBackScrimAlpha) {
+ mCurrentBehindAlpha = 1;
+ }
+
setScrimInFrontAlpha(mCurrentInFrontAlpha);
setScrimBehindAlpha(mCurrentBehindAlpha);
@@ -398,12 +460,18 @@
}
private void dispatchScrimsVisible() {
- boolean scrimsVisible = mScrimBehind.getViewAlpha() > 0 || mScrimInFront.getViewAlpha() > 0;
+ final int currentScrimVisibility;
+ if (mScrimInFront.getViewAlpha() == 1 || mScrimBehind.getViewAlpha() == 1) {
+ currentScrimVisibility = VISIBILITY_FULLY_OPAQUE;
+ } else if (mScrimInFront.getViewAlpha() == 0 && mScrimBehind.getViewAlpha() == 0) {
+ currentScrimVisibility = VISIBILITY_FULLY_TRANSPARENT;
+ } else {
+ currentScrimVisibility = VISIBILITY_SEMI_TRANSPARENT;
+ }
- if (mScrimsVisible != scrimsVisible) {
- mScrimsVisible = scrimsVisible;
-
- mScrimVisibleListener.accept(scrimsVisible);
+ if (mScrimsVisibility != currentScrimVisibility) {
+ mScrimsVisibility = currentScrimVisibility;
+ mScrimVisibleListener.accept(currentScrimVisibility);
}
}
@@ -811,6 +879,14 @@
pw.print(" mTracking="); pw.println(mTracking);
}
+ public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) {
+ mWallpaperSupportsAmbientMode = wallpaperSupportsAmbientMode;
+ ScrimState[] states = ScrimState.values();
+ for (int i = 0; i < states.length; i++) {
+ states[i].setWallpaperSupportsAmbientMode(wallpaperSupportsAmbientMode);
+ }
+ }
+
public interface Callback {
default void onStart() {
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index c33cc50..fa2c1b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -19,6 +19,7 @@
import android.graphics.Color;
import android.os.Trace;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.stack.StackStateAnimator;
@@ -89,8 +90,10 @@
updateScrimColor(mScrimInFront, 1, Color.BLACK);
}
final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
- mBlankScreen = previousState == ScrimState.PULSING;
- mCurrentBehindAlpha = 1;
+ final boolean wasPulsing = previousState == ScrimState.PULSING;
+ mBlankScreen = wasPulsing && !mCanControlScreenOff;
+ mCurrentBehindAlpha = mWallpaperSupportsAmbientMode
+ && !mKeyguardUpdateMonitor.hasLockscreenWallpaper() ? 0f : 1f;
mCurrentInFrontAlpha = alwaysOnEnabled ? mAodFrontScrimAlpha : 1f;
mCurrentInFrontTint = Color.BLACK;
mCurrentBehindTint = Color.BLACK;
@@ -106,9 +109,10 @@
PULSING {
@Override
public void prepare(ScrimState previousState) {
- mCurrentBehindAlpha = 1;
mCurrentInFrontAlpha = 0;
mCurrentInFrontTint = Color.BLACK;
+ mCurrentBehindAlpha = mWallpaperSupportsAmbientMode
+ && !mKeyguardUpdateMonitor.hasLockscreenWallpaper() ? 0f : 1f;
mCurrentBehindTint = Color.BLACK;
mBlankScreen = mDisplayRequiresBlanking;
if (mDisplayRequiresBlanking) {
@@ -158,6 +162,8 @@
DozeParameters mDozeParameters;
boolean mDisplayRequiresBlanking;
boolean mCanControlScreenOff;
+ boolean mWallpaperSupportsAmbientMode;
+ KeyguardUpdateMonitor mKeyguardUpdateMonitor;
public void init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters) {
mScrimInFront = scrimInFront;
@@ -165,6 +171,7 @@
mDozeParameters = dozeParameters;
mDisplayRequiresBlanking = dozeParameters.getDisplayNeedsBlanking();
mCanControlScreenOff = dozeParameters.getCanControlScreenOffAnimation();
+ mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(scrimInFront.getContext());
}
public void prepare(ScrimState previousState) {
@@ -218,4 +225,8 @@
public void setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard) {
mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
}
+
+ public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) {
+ mWallpaperSupportsAmbientMode = wallpaperSupportsAmbientMode;
+ }
}
\ No newline at end of file
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 fecd6bd..c5349d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -46,6 +46,7 @@
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
+import android.app.AlarmManager;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -53,6 +54,7 @@
import android.app.StatusBarManager;
import android.app.TaskStackBuilder;
import android.app.WallpaperColors;
+import android.app.WallpaperInfo;
import android.app.WallpaperManager;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
@@ -249,7 +251,6 @@
import java.util.List;
import java.util.Map;
import java.util.Stack;
-import java.util.function.Function;
public class StatusBar extends SystemUI implements DemoMode,
DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
@@ -526,7 +527,22 @@
protected NotificationLockscreenUserManager mLockscreenUserManager;
protected NotificationRemoteInputManager mRemoteInputManager;
+ private BroadcastReceiver mWallpaperChangedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class);
+ if (wallpaperManager == null) {
+ Log.w(TAG, "WallpaperManager not available");
+ return;
+ }
+ WallpaperInfo info = wallpaperManager.getWallpaperInfo();
+ final boolean supportsAmbientMode = info != null &&
+ info.getSupportsAmbientMode();
+ mStatusBarWindowManager.setWallpaperSupportsAmbientMode(supportsAmbientMode);
+ mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
+ }
+ };
private Runnable mLaunchTransitionEndRunnable;
protected boolean mLaunchTransitionFadingAway;
@@ -704,6 +720,11 @@
createAndAddWindows();
+ // Make sure we always have the most current wallpaper info.
+ IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
+ mContext.registerReceiver(mWallpaperChangedReceiver, wallpaperChangedFilter);
+ mWallpaperChangedReceiver.onReceive(mContext, null);
+
mCommandQueue.disable(switches[0], switches[6], false /* animate */);
setSystemUiVisibility(switches[1], switches[7], switches[8], 0xffffffff,
fullscreenStackBounds, dockedStackBounds);
@@ -922,9 +943,9 @@
scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper,
scrimsVisible -> {
if (mStatusBarWindowManager != null) {
- mStatusBarWindowManager.setScrimsVisible(scrimsVisible);
+ mStatusBarWindowManager.setScrimsVisibility(scrimsVisible);
}
- }, new DozeParameters(mContext));
+ }, new DozeParameters(mContext), mContext.getSystemService(AlarmManager.class));
if (mScrimSrcModeEnabled) {
Runnable runnable = () -> {
boolean asSrc = mBackdrop.getVisibility() != View.VISIBLE;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index b0b5b8e..c30f633 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -54,6 +54,7 @@
private final Context mContext;
private final WindowManager mWindowManager;
private final IActivityManager mActivityManager;
+ private final DozeParameters mDozeParameters;
private View mStatusBarView;
private WindowManager.LayoutParams mLp;
private WindowManager.LayoutParams mLpChanged;
@@ -70,8 +71,8 @@
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mActivityManager = ActivityManager.getService();
mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
- mScreenBrightnessDoze = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_screenBrightnessDoze) / 255f;
+ mDozeParameters = new DozeParameters(mContext);
+ mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
}
private boolean shouldEnableKeyguardScreenRotation() {
@@ -136,7 +137,11 @@
mLpChanged.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
}
- if (state.keyguardShowing && !state.backdropShowing && !state.dozing) {
+ final boolean showWallpaperOnAod = mDozeParameters.getAlwaysOn() &&
+ state.wallpaperSupportsAmbientMode &&
+ state.scrimsVisibility != ScrimController.VISIBILITY_FULLY_OPAQUE;
+ if (state.keyguardShowing && !state.backdropShowing &&
+ (!state.dozing || showWallpaperOnAod)) {
mLpChanged.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
} else {
mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
@@ -188,7 +193,8 @@
private boolean isExpanded(State state) {
return !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded()
|| state.panelVisible || state.keyguardFadingAway || state.bouncerShowing
- || state.headsUpShowing || state.scrimsVisible);
+ || state.headsUpShowing
+ || state.scrimsVisibility != ScrimController.VISIBILITY_FULLY_TRANSPARENT);
}
private void applyFitsSystemWindows(State state) {
@@ -336,8 +342,8 @@
apply(mCurrentState);
}
- public void setScrimsVisible(boolean scrimsVisible) {
- mCurrentState.scrimsVisible = scrimsVisible;
+ public void setScrimsVisibility(int scrimsVisibility) {
+ mCurrentState.scrimsVisibility = scrimsVisibility;
apply(mCurrentState);
}
@@ -346,6 +352,11 @@
apply(mCurrentState);
}
+ public void setWallpaperSupportsAmbientMode(boolean supportsAmbientMode) {
+ mCurrentState.wallpaperSupportsAmbientMode = supportsAmbientMode;
+ apply(mCurrentState);
+ }
+
/**
* @param state The {@link StatusBarState} of the status bar.
*/
@@ -433,6 +444,7 @@
boolean forceDozeBrightness;
boolean forceUserActivity;
boolean backdropShowing;
+ boolean wallpaperSupportsAmbientMode;
/**
* The {@link StatusBar} state from the status bar.
@@ -442,7 +454,7 @@
boolean remoteInputActive;
boolean forcePluginOpen;
boolean dozing;
- boolean scrimsVisible;
+ int scrimsVisibility;
private boolean isKeyguardShowingAndNotOccluded() {
return keyguardShowing && !keyguardOccluded;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
new file mode 100644
index 0000000..8e7f83d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.doze;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.IWallpaperManager;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.support.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+@SmallTest
+public class DozeWallpaperStateTest extends SysuiTestCase {
+
+ @Test
+ public void testDreamNotification() throws RemoteException {
+ IWallpaperManager wallpaperManagerService = mock(IWallpaperManager.class);
+ DozeWallpaperState dozeWallpaperState = new DozeWallpaperState(wallpaperManagerService);
+ dozeWallpaperState.transitionTo(DozeMachine.State.UNINITIALIZED,
+ DozeMachine.State.DOZE_AOD);
+ verify(wallpaperManagerService).setInAmbientMode(eq(true));
+ dozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.FINISH);
+ verify(wallpaperManagerService).setInAmbientMode(eq(false));
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index a40ef64..6d2691c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -16,13 +16,22 @@
package com.android.systemui.statusbar.phone;
+import static com.android.systemui.statusbar.phone.ScrimController.VISIBILITY_FULLY_OPAQUE;
+import static com.android.systemui.statusbar.phone.ScrimController.VISIBILITY_FULLY_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.ScrimController.VISIBILITY_SEMI_TRANSPARENT;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.animation.Animator;
+import android.app.AlarmManager;
import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
@@ -31,6 +40,7 @@
import android.testing.TestableLooper;
import android.view.View;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.util.wakelock.WakeLock;
@@ -52,12 +62,13 @@
private ScrimView mScrimBehind;
private ScrimView mScrimInFront;
private View mHeadsUpScrim;
- private Consumer<Boolean> mScrimVisibilityCallback;
- private Boolean mScrimVisibile;
+ private Consumer<Integer> mScrimVisibilityCallback;
+ private int mScrimVisibility;
private LightBarController mLightBarController;
private DozeParameters mDozeParamenters;
private WakeLock mWakeLock;
private boolean mAlwaysOnEnabled;
+ private AlarmManager mAlarmManager;
@Before
public void setup() {
@@ -66,13 +77,15 @@
mScrimInFront = new ScrimView(getContext());
mHeadsUpScrim = mock(View.class);
mWakeLock = mock(WakeLock.class);
+ mAlarmManager = mock(AlarmManager.class);
mAlwaysOnEnabled = true;
- mScrimVisibilityCallback = (Boolean visible) -> mScrimVisibile = visible;
+ mScrimVisibilityCallback = (Integer visible) -> mScrimVisibility = visible;
mDozeParamenters = mock(DozeParameters.class);
when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true);
mScrimController = new SynchronousScrimController(mLightBarController, mScrimBehind,
- mScrimInFront, mHeadsUpScrim, mScrimVisibilityCallback, mDozeParamenters);
+ mScrimInFront, mHeadsUpScrim, mScrimVisibilityCallback, mDozeParamenters,
+ mAlarmManager);
}
@Test
@@ -87,29 +100,70 @@
mScrimController.finishAnimationsImmediately();
// Front scrim should be transparent
// Back scrim should be visible without tint
- assertScrimVisibility(false /* front */, true /* behind */);
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
assertScrimTint(mScrimBehind, false /* tinted */);
}
@Test
- public void transitionToAod() {
+ public void transitionToAod_withRegularWallpaper() {
mScrimController.transitionTo(ScrimState.AOD);
mScrimController.finishAnimationsImmediately();
// Front scrim should be transparent
// Back scrim should be visible with tint
- assertScrimVisibility(false /* front */, true /* behind */);
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
+ assertScrimTint(mScrimBehind, true /* tinted */);
+ assertScrimTint(mScrimInFront, true /* tinted */);
+ }
+
+ @Test
+ public void transitionToAod_withAodWallpaper() {
+ mScrimController.setWallpaperSupportsAmbientMode(true);
+ mScrimController.transitionTo(ScrimState.AOD);
+ mScrimController.finishAnimationsImmediately();
+ // Front scrim should be transparent
+ // Back scrim should be transparent
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
+
+ // Move on to PULSING and check if the back scrim is still transparent
+ mScrimController.transitionTo(ScrimState.PULSING);
+ mScrimController.finishAnimationsImmediately();
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
+ }
+
+ @Test
+ public void transitionToAod_withAodWallpaperAndLockScreenWallpaper() {
+ ScrimState.AOD.mKeyguardUpdateMonitor = new KeyguardUpdateMonitor(getContext()) {
+ @Override
+ public boolean hasLockscreenWallpaper() {
+ return true;
+ }
+ };
+ mScrimController.setWallpaperSupportsAmbientMode(true);
+ mScrimController.transitionTo(ScrimState.AOD);
+ mScrimController.finishAnimationsImmediately();
+ // Front scrim should be transparent
+ // Back scrim should be visible with tint
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
assertScrimTint(mScrimBehind, true /* tinted */);
assertScrimTint(mScrimInFront, true /* tinted */);
}
@Test
public void transitionToPulsing() {
+ // Pre-condition
+ // Need to go to AoD first because PULSING doesn't change
+ // the back scrim opacity - otherwise it would hide AoD wallpapers.
+ mScrimController.setWallpaperSupportsAmbientMode(false);
+ mScrimController.transitionTo(ScrimState.AOD);
+ mScrimController.finishAnimationsImmediately();
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
+
mScrimController.transitionTo(ScrimState.PULSING);
mScrimController.finishAnimationsImmediately();
// Front scrim should be transparent
// Back scrim should be visible with tint
// Pulse callback should have been invoked
- assertScrimVisibility(false /* front */, true /* behind */);
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
assertScrimTint(mScrimBehind, true /* tinted */);
}
@@ -119,7 +173,7 @@
mScrimController.finishAnimationsImmediately();
// Front scrim should be transparent
// Back scrim should be visible without tint
- assertScrimVisibility(true /* front */, true /* behind */);
+ assertScrimVisibility(VISIBILITY_SEMI_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
assertScrimTint(mScrimBehind, false /* tinted */);
}
@@ -129,13 +183,13 @@
mScrimController.finishAnimationsImmediately();
// Front scrim should be transparent
// Back scrim should be transparent
- assertScrimVisibility(false /* front */, false /* behind */);
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
assertScrimTint(mScrimBehind, false /* tinted */);
assertScrimTint(mScrimInFront, false /* tinted */);
// Back scrim should be visible after start dragging
mScrimController.setPanelExpansion(0.5f);
- assertScrimVisibility(false /* front */, true /* behind */);
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
}
@Test
@@ -151,7 +205,7 @@
// Front scrim should be transparent
// Back scrim should be transparent
// Neither scrims should be tinted anymore after the animation.
- assertScrimVisibility(false /* front */, false /* behind */);
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
assertScrimTint(mScrimInFront, false /* tinted */);
assertScrimTint(mScrimBehind, false /* tinted */);
}
@@ -169,8 +223,8 @@
Assert.assertTrue("Scrim should be visible during transition. Alpha: "
+ mScrimInFront.getViewAlpha(), mScrimInFront.getViewAlpha() > 0);
assertScrimTint(mScrimInFront, true /* tinted */);
- Assert.assertTrue("Scrim should be visible during transition.",
- mScrimVisibile);
+ Assert.assertSame("Scrim should be visible during transition.",
+ mScrimVisibility, VISIBILITY_FULLY_OPAQUE);
}
});
mScrimController.finishAnimationsImmediately();
@@ -222,12 +276,19 @@
}
@Test
- public void testHoldsWakeLock() {
+ public void testHoldsWakeLock_whenAOD() {
mScrimController.transitionTo(ScrimState.AOD);
- verify(mWakeLock, times(1)).acquire();
+ verify(mWakeLock).acquire();
verify(mWakeLock, never()).release();
mScrimController.finishAnimationsImmediately();
- verify(mWakeLock, times(1)).release();
+ verify(mWakeLock).release();
+ }
+
+ @Test
+ public void testDoesNotHoldWakeLock_whenUnlocking() {
+ mScrimController.transitionTo(ScrimState.UNLOCKED);
+ mScrimController.finishAnimationsImmediately();
+ verifyZeroInteractions(mWakeLock);
}
@Test
@@ -236,7 +297,30 @@
mScrimController.finishAnimationsImmediately();
ScrimController.Callback callback = mock(ScrimController.Callback.class);
mScrimController.transitionTo(ScrimState.UNLOCKED, callback);
- verify(callback, times(1)).onFinished();
+ verify(callback).onFinished();
+ }
+
+ @Test
+ public void testHoldsAodWallpaperAnimationLock() {
+ // Pre-conditions
+ mScrimController.transitionTo(ScrimState.AOD);
+ mScrimController.finishAnimationsImmediately();
+ reset(mWakeLock);
+
+ mScrimController.onHideWallpaperTimeout();
+ verify(mWakeLock).acquire();
+ verify(mWakeLock, never()).release();
+ mScrimController.finishAnimationsImmediately();
+ verify(mWakeLock).release();
+ }
+
+ @Test
+ public void testWillHideAoDWallpaper() {
+ mScrimController.setWallpaperSupportsAmbientMode(true);
+ mScrimController.transitionTo(ScrimState.AOD);
+ verify(mAlarmManager).setExact(anyInt(), anyLong(), any(), any(), any());
+ mScrimController.transitionTo(ScrimState.KEYGUARD);
+ verify(mAlarmManager).cancel(any(AlarmManager.OnAlarmListener.class));
}
private void assertScrimTint(ScrimView scrimView, boolean tinted) {
@@ -247,12 +331,23 @@
tinted, viewIsTinted);
}
- private void assertScrimVisibility(boolean inFront, boolean behind) {
+ private void assertScrimVisibility(int inFront, int behind) {
+ boolean inFrontVisible = inFront != ScrimController.VISIBILITY_FULLY_TRANSPARENT;
+ boolean behindVisible = behind != ScrimController.VISIBILITY_FULLY_TRANSPARENT;
Assert.assertEquals("Unexpected front scrim visibility. Alpha is "
- + mScrimInFront.getViewAlpha(), inFront, mScrimInFront.getViewAlpha() > 0);
+ + mScrimInFront.getViewAlpha(), inFrontVisible, mScrimInFront.getViewAlpha() > 0);
Assert.assertEquals("Unexpected back scrim visibility. Alpha is "
- + mScrimBehind.getViewAlpha(), behind, mScrimBehind.getViewAlpha() > 0);
- Assert.assertEquals("Invalid visibility.", inFront || behind, mScrimVisibile);
+ + mScrimBehind.getViewAlpha(), behindVisible, mScrimBehind.getViewAlpha() > 0);
+
+ final int visibility;
+ if (inFront == VISIBILITY_FULLY_OPAQUE || behind == VISIBILITY_FULLY_OPAQUE) {
+ visibility = VISIBILITY_FULLY_OPAQUE;
+ } else if (inFront > VISIBILITY_FULLY_TRANSPARENT || behind > VISIBILITY_FULLY_TRANSPARENT) {
+ visibility = VISIBILITY_SEMI_TRANSPARENT;
+ } else {
+ visibility = VISIBILITY_FULLY_TRANSPARENT;
+ }
+ Assert.assertEquals("Invalid visibility.", visibility, mScrimVisibility);
}
/**
@@ -264,9 +359,10 @@
public SynchronousScrimController(LightBarController lightBarController,
ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
- Consumer<Boolean> scrimVisibleListener, DozeParameters dozeParameters) {
+ Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
+ AlarmManager alarmManager) {
super(lightBarController, scrimBehind, scrimInFront, headsUpScrim,
- scrimVisibleListener, dozeParameters);
+ scrimVisibleListener, dozeParameters, alarmManager);
mHandler = new FakeHandler(Looper.myLooper());
}
diff --git a/packages/VpnDialogs/res/values-ne/strings.xml b/packages/VpnDialogs/res/values-ne/strings.xml
index c19ae52..5019a06 100644
--- a/packages/VpnDialogs/res/values-ne/strings.xml
+++ b/packages/VpnDialogs/res/values-ne/strings.xml
@@ -25,8 +25,8 @@
<string name="data_received" msgid="4062776929376067820">"प्राप्त भयो:"</string>
<string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> बाइटहरू / <xliff:g id="NUMBER_1">%2$s</xliff:g> प्याकेटहरू"</string>
<string name="always_on_disconnected_title" msgid="1906740176262776166">"सधैँ-सक्रिय रहने VPN सेवामा जडान गर्न सकिँदैन"</string>
- <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> लाई सधैँ जडान भइरहनेगरि सेट अप गरिएको छ तर यसलाई अहिले नै जडान गर्न मिल्दैन। तपाईंको फोन <xliff:g id="VPN_APP_1">%1$s</xliff:g> मा पुन: जडान नहुँदासम्म यसले कुनै सार्वजनिक नेटवर्क प्रयोग गर्नेछ।"</string>
- <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> लाई सधैँ पनि जडान भइरहनेगरि सेट अप गरिएको छ तर यसलाई अहिले नै जडान गर्न मिल्दैन। VPN पुन: जडान नहुँदासम्म तपाईंसँग कुनै पनि इन्टरनेट रहनेछैन।"</string>
+ <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> लाई सधैँ जडान भइरहनेगरि सेटअप गरिएको छ तर यसलाई अहिले नै जडान गर्न मिल्दैन। तपाईंको फोन <xliff:g id="VPN_APP_1">%1$s</xliff:g> मा पुन: जडान नहुँदासम्म यसले कुनै सार्वजनिक नेटवर्क प्रयोग गर्नेछ।"</string>
+ <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> लाई सधैँ पनि जडान भइरहनेगरि सेटअप गरिएको छ तर यसलाई अहिले नै जडान गर्न मिल्दैन। VPN पुन: जडान नहुँदासम्म तपाईंसँग कुनै पनि इन्टरनेट रहनेछैन।"</string>
<string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
<string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN सम्बन्धी सेटिङहरू परिवर्तन गर्नुहोस्"</string>
<string name="configure" msgid="4905518375574791375">"कन्फिगर गर्नुहोस्"</string>
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index e9eb3b3..a764808 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -34,6 +34,7 @@
import android.net.IpSecTransformResponse;
import android.net.IpSecUdpEncapResponse;
import android.net.NetworkUtils;
+import android.net.TrafficStats;
import android.net.util.NetdService;
import android.os.Binder;
import android.os.IBinder;
@@ -120,6 +121,7 @@
}
private final IpSecServiceConfiguration mSrvConfig;
+ final UidFdTagger mUidFdTagger;
/**
* Interface for user-reference and kernel-resource cleanup.
@@ -762,8 +764,23 @@
/** @hide */
@VisibleForTesting
public IpSecService(Context context, IpSecServiceConfiguration config) {
+ this(context, config, (fd, uid) -> {
+ try{
+ TrafficStats.setThreadStatsUid(uid);
+ TrafficStats.tagFileDescriptor(fd);
+ } finally {
+ TrafficStats.clearThreadStatsUid();
+ }
+ });
+ }
+
+ /** @hide */
+ @VisibleForTesting
+ public IpSecService(
+ Context context, IpSecServiceConfiguration config, UidFdTagger uidFdTagger) {
mContext = context;
mSrvConfig = config;
+ mUidFdTagger = uidFdTagger;
}
public void systemReady() {
@@ -925,6 +942,26 @@
}
/**
+ * Functional interface to do traffic tagging of given sockets to UIDs.
+ *
+ * <p>Specifically used by openUdpEncapsulationSocket to ensure data usage on the UDP encap
+ * sockets are billed to the UID that the UDP encap socket was created on behalf of.
+ *
+ * <p>Separate class so that the socket tagging logic can be mocked; TrafficStats uses static
+ * methods that cannot be easily mocked/tested.
+ */
+ @VisibleForTesting
+ public interface UidFdTagger {
+ /**
+ * Sets socket tag to assign all traffic to the provided UID.
+ *
+ * <p>Since the socket is created on behalf of an unprivileged application, all traffic
+ * should be accounted to the UID of the unprivileged application.
+ */
+ public void tag(FileDescriptor fd, int uid) throws IOException;
+ }
+
+ /**
* Open a socket via the system server and bind it to the specified port (random if port=0).
* This will return a PFD to the user that represent a bound UDP socket. The system server will
* cache the socket and a record of its owner so that it can and must be freed when no longer
@@ -939,7 +976,8 @@
}
checkNotNull(binder, "Null Binder passed to openUdpEncapsulationSocket");
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+ int callingUid = Binder.getCallingUid();
+ UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
int resourceId = mNextResourceId.getAndIncrement();
FileDescriptor sockFd = null;
try {
@@ -948,6 +986,7 @@
}
sockFd = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ mUidFdTagger.tag(sockFd, callingUid);
if (port != 0) {
Log.v(TAG, "Binding to port " + port);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 3cd2f6a..088ddea 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2640,7 +2640,7 @@
try {
bumpServiceExecutingLocked(s, false, "unbind");
if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
- && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
+ && s.app.setProcState <= ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
// If this service's process is not already in the cached list,
// then update it in the LRU list here because this may be causing
// it to go down there and we want it to start out near the top.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index eaa7108..7dfde56 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -391,6 +391,7 @@
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.BinderInternal;
+import com.android.internal.os.ByteTransferPipe;
import com.android.internal.os.IResultReceiver;
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.TransferPipe;
@@ -14145,8 +14146,7 @@
for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
ProcessRecord proc = mLruProcesses.get(i);
if (proc.notCachedSinceIdle) {
- if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
- && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
+ if (proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
&& proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
if (doKilling && proc.initialIdlePss != 0
&& proc.lastPss > ((proc.initialIdlePss*3)/2)) {
@@ -17241,20 +17241,24 @@
}
}
+ private static void sortMemItems(List<MemItem> items) {
+ Collections.sort(items, new Comparator<MemItem>() {
+ @Override
+ public int compare(MemItem lhs, MemItem rhs) {
+ if (lhs.pss < rhs.pss) {
+ return 1;
+ } else if (lhs.pss > rhs.pss) {
+ return -1;
+ }
+ return 0;
+ }
+ });
+ }
+
static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
if (sort && !isCompact) {
- Collections.sort(items, new Comparator<MemItem>() {
- @Override
- public int compare(MemItem lhs, MemItem rhs) {
- if (lhs.pss < rhs.pss) {
- return 1;
- } else if (lhs.pss > rhs.pss) {
- return -1;
- }
- return 0;
- }
- });
+ sortMemItems(items);
}
for (int i=0; i<items.size(); i++) {
@@ -17282,6 +17286,33 @@
}
}
+ static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
+ ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
+ if (sort) {
+ sortMemItems(items);
+ }
+
+ for (int i=0; i<items.size(); i++) {
+ MemItem mi = items.get(i);
+ final long token = proto.start(fieldId);
+
+ proto.write(MemInfoProto.MemItem.TAG, tag);
+ proto.write(MemInfoProto.MemItem.LABEL, mi.shortLabel);
+ proto.write(MemInfoProto.MemItem.IS_PROC, mi.isProc);
+ proto.write(MemInfoProto.MemItem.ID, mi.id);
+ proto.write(MemInfoProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
+ proto.write(MemInfoProto.MemItem.PSS_KB, mi.pss);
+ if (dumpSwapPss) {
+ proto.write(MemInfoProto.MemItem.SWAP_PSS_KB, mi.swapPss);
+ }
+ if (mi.subitems != null) {
+ dumpMemItems(proto, MemInfoProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
+ true, dumpSwapPss);
+ }
+ proto.end(token);
+ }
+ }
+
// These are in KB.
static final long[] DUMP_MEM_BUCKETS = new long[] {
5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
@@ -17493,7 +17524,7 @@
ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
if (opts.dumpProto) {
- dumpApplicationMemoryUsage(fd, pw, opts, innerArgs, brief, procs);
+ dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
} else {
dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
}
@@ -17983,7 +18014,7 @@
}
}
- private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw,
+ private final void dumpApplicationMemoryUsage(FileDescriptor fd,
MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
ArrayList<ProcessRecord> procs) {
final long uptimeMs = SystemClock.uptimeMillis();
@@ -18025,8 +18056,8 @@
final int pid = r.pid;
final long nToken = proto.start(MemInfoProto.NATIVE_PROCESSES);
- proto.write(MemInfoProto.NativeProcess.PID, pid);
- proto.write(MemInfoProto.NativeProcess.PROCESS_NAME, r.baseName);
+ proto.write(MemInfoProto.ProcessMemory.PID, pid);
+ proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.baseName);
if (mi == null) {
mi = new Debug.MemoryInfo();
@@ -18052,8 +18083,332 @@
return;
}
- // TODO: finish
- pw.println("Java processes aren't implemented yet. Have a coffee instead! :]");
+ if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
+ opts.dumpDetails = true;
+ }
+
+ ProtoOutputStream proto = new ProtoOutputStream(fd);
+
+ proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
+ proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
+
+ ArrayList<MemItem> procMems = new ArrayList<MemItem>();
+ final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
+ long nativePss = 0;
+ long nativeSwapPss = 0;
+ long dalvikPss = 0;
+ long dalvikSwapPss = 0;
+ long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
+ EmptyArray.LONG;
+ long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
+ EmptyArray.LONG;
+ long otherPss = 0;
+ long otherSwapPss = 0;
+ long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
+ long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
+
+ long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
+ long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
+ ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
+ new ArrayList[DUMP_MEM_OOM_LABEL.length];
+
+ long totalPss = 0;
+ long totalSwapPss = 0;
+ long cachedPss = 0;
+ long cachedSwapPss = 0;
+ boolean hasSwapPss = false;
+
+ Debug.MemoryInfo mi = null;
+ for (int i = procs.size() - 1 ; i >= 0 ; i--) {
+ final ProcessRecord r = procs.get(i);
+ final IApplicationThread thread;
+ final int pid;
+ final int oomAdj;
+ final boolean hasActivities;
+ synchronized (this) {
+ thread = r.thread;
+ pid = r.pid;
+ oomAdj = r.getSetAdjWithServices();
+ hasActivities = r.activities.size() > 0;
+ }
+ if (thread == null) {
+ continue;
+ }
+ if (mi == null) {
+ mi = new Debug.MemoryInfo();
+ }
+ if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
+ Debug.getMemoryInfo(pid, mi);
+ hasSwapPss = mi.hasSwappedOutPss;
+ } else {
+ mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
+ mi.dalvikPrivateDirty = (int) tmpLong[0];
+ }
+ if (opts.dumpDetails) {
+ if (opts.localOnly) {
+ final long aToken = proto.start(MemInfoProto.APP_PROCESSES);
+ final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
+ proto.write(MemInfoProto.ProcessMemory.PID, pid);
+ proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.processName);
+ ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
+ opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
+ proto.end(mToken);
+ proto.end(aToken);
+ } else {
+ try {
+ ByteTransferPipe tp = new ByteTransferPipe();
+ try {
+ thread.dumpMemInfoProto(tp.getWriteFd(),
+ mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
+ opts.dumpUnreachable, innerArgs);
+ proto.write(MemInfoProto.APP_PROCESSES, tp.get());
+ } finally {
+ tp.kill();
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Got IOException!", e);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Got RemoteException!", e);
+ }
+ }
+ }
+
+ final long myTotalPss = mi.getTotalPss();
+ final long myTotalUss = mi.getTotalUss();
+ final long myTotalSwapPss = mi.getTotalSwappedOutPss();
+
+ synchronized (this) {
+ if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
+ // Record this for posterity if the process has been stable.
+ r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
+ }
+ }
+
+ if (!opts.isCheckinRequest && mi != null) {
+ totalPss += myTotalPss;
+ totalSwapPss += myTotalSwapPss;
+ MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
+ (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
+ myTotalSwapPss, pid, hasActivities);
+ procMems.add(pssItem);
+ procMemsMap.put(pid, pssItem);
+
+ nativePss += mi.nativePss;
+ nativeSwapPss += mi.nativeSwappedOutPss;
+ dalvikPss += mi.dalvikPss;
+ dalvikSwapPss += mi.dalvikSwappedOutPss;
+ for (int j=0; j<dalvikSubitemPss.length; j++) {
+ dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
+ dalvikSubitemSwapPss[j] +=
+ mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
+ }
+ otherPss += mi.otherPss;
+ otherSwapPss += mi.otherSwappedOutPss;
+ for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
+ long mem = mi.getOtherPss(j);
+ miscPss[j] += mem;
+ otherPss -= mem;
+ mem = mi.getOtherSwappedOutPss(j);
+ miscSwapPss[j] += mem;
+ otherSwapPss -= mem;
+ }
+
+ if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
+ cachedPss += myTotalPss;
+ cachedSwapPss += myTotalSwapPss;
+ }
+
+ for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
+ if (oomIndex == (oomPss.length - 1)
+ || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
+ && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
+ oomPss[oomIndex] += myTotalPss;
+ oomSwapPss[oomIndex] += myTotalSwapPss;
+ if (oomProcs[oomIndex] == null) {
+ oomProcs[oomIndex] = new ArrayList<MemItem>();
+ }
+ oomProcs[oomIndex].add(pssItem);
+ break;
+ }
+ }
+ }
+ }
+
+ long nativeProcTotalPss = 0;
+
+ if (procs.size() > 1 && !opts.packages) {
+ // If we are showing aggregations, also look for native processes to
+ // include so that our aggregations are more accurate.
+ updateCpuStatsNow();
+ mi = null;
+ synchronized (mProcessCpuTracker) {
+ final int N = mProcessCpuTracker.countStats();
+ for (int i=0; i<N; i++) {
+ ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
+ if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
+ if (mi == null) {
+ mi = new Debug.MemoryInfo();
+ }
+ if (!brief && !opts.oomOnly) {
+ Debug.getMemoryInfo(st.pid, mi);
+ } else {
+ mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
+ mi.nativePrivateDirty = (int)tmpLong[0];
+ }
+
+ final long myTotalPss = mi.getTotalPss();
+ final long myTotalSwapPss = mi.getTotalSwappedOutPss();
+ totalPss += myTotalPss;
+ nativeProcTotalPss += myTotalPss;
+
+ MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
+ st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
+ procMems.add(pssItem);
+
+ nativePss += mi.nativePss;
+ nativeSwapPss += mi.nativeSwappedOutPss;
+ dalvikPss += mi.dalvikPss;
+ dalvikSwapPss += mi.dalvikSwappedOutPss;
+ for (int j=0; j<dalvikSubitemPss.length; j++) {
+ dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
+ dalvikSubitemSwapPss[j] +=
+ mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
+ }
+ otherPss += mi.otherPss;
+ otherSwapPss += mi.otherSwappedOutPss;
+ for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
+ long mem = mi.getOtherPss(j);
+ miscPss[j] += mem;
+ otherPss -= mem;
+ mem = mi.getOtherSwappedOutPss(j);
+ miscSwapPss[j] += mem;
+ otherSwapPss -= mem;
+ }
+ oomPss[0] += myTotalPss;
+ oomSwapPss[0] += myTotalSwapPss;
+ if (oomProcs[0] == null) {
+ oomProcs[0] = new ArrayList<MemItem>();
+ }
+ oomProcs[0].add(pssItem);
+ }
+ }
+ }
+
+ ArrayList<MemItem> catMems = new ArrayList<MemItem>();
+
+ catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
+ final int dalvikId = -2;
+ catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
+ catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
+ for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
+ String label = Debug.MemoryInfo.getOtherLabel(j);
+ catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
+ }
+ if (dalvikSubitemPss.length > 0) {
+ // Add dalvik subitems.
+ for (MemItem memItem : catMems) {
+ int memItemStart = 0, memItemEnd = 0;
+ if (memItem.id == dalvikId) {
+ memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
+ memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
+ } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
+ memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
+ memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
+ } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
+ memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
+ memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
+ } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
+ memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
+ memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
+ } else {
+ continue; // No subitems, continue.
+ }
+ memItem.subitems = new ArrayList<MemItem>();
+ for (int j=memItemStart; j<=memItemEnd; j++) {
+ final String name = Debug.MemoryInfo.getOtherLabel(
+ Debug.MemoryInfo.NUM_OTHER_STATS + j);
+ memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
+ dalvikSubitemSwapPss[j], j));
+ }
+ }
+ }
+
+ ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
+ for (int j=0; j<oomPss.length; j++) {
+ if (oomPss[j] != 0) {
+ String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
+ : DUMP_MEM_OOM_LABEL[j];
+ MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
+ DUMP_MEM_OOM_ADJ[j]);
+ item.subitems = oomProcs[j];
+ oomMems.add(item);
+ }
+ }
+
+ opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
+ if (!opts.oomOnly) {
+ dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_PROCESS, "proc",
+ procMems, true, opts.dumpSwapPss);
+ }
+ dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
+ oomMems, false, opts.dumpSwapPss);
+ if (!brief && !opts.oomOnly) {
+ dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_CATEGORY, "cat",
+ catMems, true, opts.dumpSwapPss);
+ }
+ MemInfoReader memInfo = new MemInfoReader();
+ memInfo.readMemInfo();
+ if (nativeProcTotalPss > 0) {
+ synchronized (this) {
+ final long cachedKb = memInfo.getCachedSizeKb();
+ final long freeKb = memInfo.getFreeSizeKb();
+ final long zramKb = memInfo.getZramTotalSizeKb();
+ final long kernelKb = memInfo.getKernelUsedSizeKb();
+ EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
+ kernelKb*1024, nativeProcTotalPss*1024);
+ mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
+ nativeProcTotalPss);
+ }
+ }
+ if (!brief) {
+ proto.write(MemInfoProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
+ proto.write(MemInfoProto.STATUS, mLastMemoryLevel);
+ proto.write(MemInfoProto.CACHED_PSS_KB, cachedPss);
+ proto.write(MemInfoProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
+ proto.write(MemInfoProto.FREE_KB, memInfo.getFreeSizeKb());
+ }
+ long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
+ - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
+ - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
+ proto.write(MemInfoProto.USED_PSS_KB, totalPss - cachedPss);
+ proto.write(MemInfoProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
+ proto.write(MemInfoProto.LOST_RAM_KB, lostRAM);
+ if (!brief) {
+ if (memInfo.getZramTotalSizeKb() != 0) {
+ proto.write(MemInfoProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
+ proto.write(MemInfoProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
+ memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
+ proto.write(MemInfoProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
+ }
+ final long[] ksm = getKsmInfo();
+ proto.write(MemInfoProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
+ proto.write(MemInfoProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
+ proto.write(MemInfoProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
+ proto.write(MemInfoProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
+
+ proto.write(MemInfoProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
+ proto.write(MemInfoProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
+ proto.write(MemInfoProto.OOM_KB,
+ mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
+ proto.write(MemInfoProto.RESTORE_LIMIT_KB,
+ mProcessList.getCachedRestoreThresholdKb());
+
+ proto.write(MemInfoProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
+ proto.write(MemInfoProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
+ }
+ }
+
+ proto.flush();
}
private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
@@ -21336,7 +21691,7 @@
int procState;
boolean foregroundActivities = false;
mTmpBroadcastQueue.clear();
- if (app == TOP_APP) {
+ if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
// The last app on the list is the foreground app.
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
@@ -21372,6 +21727,13 @@
procState = ActivityManager.PROCESS_STATE_SERVICE;
if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
//Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
+ } else if (app == TOP_APP) {
+ adj = ProcessList.FOREGROUND_APP_ADJ;
+ schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
+ app.adjType = "top-sleeping";
+ foregroundActivities = true;
+ procState = PROCESS_STATE_CUR_TOP;
+ if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
} else {
// As far as we know the process is empty. We may change our mind later.
schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
@@ -22820,7 +23182,7 @@
if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
isInteraction = true;
app.fgInteractionTime = 0;
- } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
+ } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
if (app.fgInteractionTime == 0) {
app.fgInteractionTime = nowElapsed;
isInteraction = false;
@@ -23254,7 +23616,8 @@
break;
}
}
- } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
+ } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
+ && !app.killedByAm) {
if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
&& app.thread != null) {
try {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index eb1636d..ab5d64c 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -364,9 +364,6 @@
case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
procState = "FGS ";
break;
- case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
- procState = "TPSL";
- break;
case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
procState = "IMPF";
break;
@@ -379,15 +376,18 @@
case ActivityManager.PROCESS_STATE_BACKUP:
procState = "BKUP";
break;
- case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
- procState = "HVY ";
- break;
case ActivityManager.PROCESS_STATE_SERVICE:
procState = "SVC ";
break;
case ActivityManager.PROCESS_STATE_RECEIVER:
procState = "RCVR";
break;
+ case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
+ procState = "TPSL";
+ break;
+ case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
+ procState = "HVY ";
+ break;
case ActivityManager.PROCESS_STATE_HOME:
procState = "HOME";
break;
@@ -485,14 +485,14 @@
PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP
PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
- PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP
- PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE
PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER
+ PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
+ PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME
PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
@@ -507,14 +507,14 @@
PSS_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
- PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
- PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
+ PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
+ PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
@@ -529,14 +529,14 @@
PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
- PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
- PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
+ PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
+ PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
@@ -545,20 +545,20 @@
PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
};
- private static final long[] sTestFirstAwakePssTimes = new long[] {
+ private static final long[] sTestFirstPssTimes = new long[] {
PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT
PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
- PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
- PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
- PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
+ PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
+ PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
- PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
+ PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
+ PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
@@ -567,20 +567,20 @@
PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
};
- private static final long[] sTestSameAwakePssTimes = new long[] {
+ private static final long[] sTestSamePssTimes = new long[] {
PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT
PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
- PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
- PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
+ PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
+ PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
@@ -601,8 +601,8 @@
boolean sleeping, long now) {
final long[] table = test
? (first
- ? sTestFirstAwakePssTimes
- : sTestSameAwakePssTimes)
+ ? sTestFirstPssTimes
+ : sTestSamePssTimes)
: (first
? sFirstAwakePssTimes
: sSameAwakePssTimes);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index efa0bf8..2d7a6ad 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3884,7 +3884,8 @@
IsInCall = telecomManager.isInCall();
Binder.restoreCallingIdentity(ident);
- return (IsInCall || getMode() == AudioManager.MODE_IN_COMMUNICATION);
+ return (IsInCall || getMode() == AudioManager.MODE_IN_COMMUNICATION ||
+ getMode() == AudioManager.MODE_IN_CALL);
}
/**
diff --git a/services/core/java/com/android/server/location/ContextHubClientBroker.java b/services/core/java/com/android/server/location/ContextHubClientBroker.java
index 41d9feb..9640e04 100644
--- a/services/core/java/com/android/server/location/ContextHubClientBroker.java
+++ b/services/core/java/com/android/server/location/ContextHubClientBroker.java
@@ -179,7 +179,7 @@
}
/**
- * Handles a nanoapp load event.
+ * Notifies the client of a nanoapp load event if the connection is open.
*
* @param nanoAppId the ID of the nanoapp that was loaded.
*/
@@ -195,7 +195,7 @@
}
/**
- * Handles a nanoapp unload event.
+ * Notifies the client of a nanoapp unload event if the connection is open.
*
* @param nanoAppId the ID of the nanoapp that was unloaded.
*/
@@ -211,7 +211,7 @@
}
/**
- * Handles a hub reset for this client.
+ * Notifies the client of a hub reset event if the connection is open.
*/
/* package */ void onHubReset() {
if (mConnectionOpen.get()) {
@@ -223,4 +223,21 @@
}
}
}
+
+ /**
+ * Notifies the client of a nanoapp abort event if the connection is open.
+ *
+ * @param nanoAppId the ID of the nanoapp that aborted
+ * @param abortCode the nanoapp specific abort code
+ */
+ /* package */ void onNanoAppAborted(long nanoAppId, int abortCode) {
+ if (mConnectionOpen.get()) {
+ try {
+ mCallbackInterface.onNanoAppAborted(nanoAppId, abortCode);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException while calling onNanoAppAborted on client"
+ + " (host endpoint ID = " + mHostEndPointId + ")", e);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/location/ContextHubClientManager.java b/services/core/java/com/android/server/location/ContextHubClientManager.java
index d58a746..60b5b1f 100644
--- a/services/core/java/com/android/server/location/ContextHubClientManager.java
+++ b/services/core/java/com/android/server/location/ContextHubClientManager.java
@@ -149,35 +149,38 @@
}
/**
- * Handles a nanoapp load event.
- *
- * @param contextHubId the ID of the hub where the nanoapp was loaded.
- * @param nanoAppId the ID of the nanoapp that was loaded.
+ * @param contextHubId the ID of the hub where the nanoapp was loaded
+ * @param nanoAppId the ID of the nanoapp that was loaded
*/
/* package */ void onNanoAppLoaded(int contextHubId, long nanoAppId) {
forEachClientOfHub(contextHubId, client -> client.onNanoAppLoaded(nanoAppId));
}
/**
- * Handles a nanoapp unload event.
- *
- * @param contextHubId the ID of the hub where the nanoapp was unloaded.
- * @param nanoAppId the ID of the nanoapp that was unloaded.
+ * @param contextHubId the ID of the hub where the nanoapp was unloaded
+ * @param nanoAppId the ID of the nanoapp that was unloaded
*/
/* package */ void onNanoAppUnloaded(int contextHubId, long nanoAppId) {
forEachClientOfHub(contextHubId, client -> client.onNanoAppUnloaded(nanoAppId));
}
/**
- * Handles a hub reset.
- *
- * @param contextHubId the ID of the hub that has reset.
+ * @param contextHubId the ID of the hub that has reset
*/
/* package */ void onHubReset(int contextHubId) {
forEachClientOfHub(contextHubId, client -> client.onHubReset());
}
/**
+ * @param contextHubId the ID of the hub that contained the nanoapp that aborted
+ * @param nanoAppId the ID of the nanoapp that aborted
+ * @param abortCode the nanoapp specific abort code
+ */
+ /* package */ void onNanoAppAborted(int contextHubId, long nanoAppId, int abortCode) {
+ forEachClientOfHub(contextHubId, client -> client.onNanoAppAborted(nanoAppId, abortCode));
+ }
+
+ /**
* Creates a new ContextHubClientBroker object for a client and registers it with the client
* manager.
*
diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java
index 1ad0cf9..7f88663 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -269,13 +269,9 @@
checkPermissions();
int[] returnArray = new int[mContextHubInfo.length];
- Log.d(TAG, "System supports " + returnArray.length + " hubs");
for (int i = 0; i < returnArray.length; ++i) {
returnArray[i] = i;
- Log.d(TAG, String.format("Hub %s is mapped to %d",
- mContextHubInfo[i].getName(), returnArray[i]));
}
-
return returnArray;
}
@@ -425,12 +421,6 @@
for (int i = 0; i < foundInstances.size(); i++) {
retArray[i] = foundInstances.get(i).intValue();
}
-
- if (retArray.length == 0) {
- Log.d(TAG, "No nanoapps found on hub ID " + hubHandle + " using NanoAppFilter: "
- + filter);
- }
-
return retArray;
}
@@ -583,7 +573,7 @@
* @param abortCode the nanoapp-specific abort code
*/
private void handleAppAbortCallback(int contextHubId, long nanoAppId, int abortCode) {
- // TODO(b/31049861): Implement this
+ mClientManager.onNanoAppAborted(contextHubId, nanoAppId, abortCode);
}
/**
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 60f451a..aa55930 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -28,6 +28,8 @@
import static com.android.internal.widget.LockPatternUtils.frpCredentialEnabled;
import static com.android.internal.widget.LockPatternUtils.userOwnsFrpCredential;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.IActivityManager;
@@ -60,6 +62,7 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
import android.os.ShellCallback;
import android.os.StrictMode;
import android.os.SystemProperties;
@@ -75,6 +78,10 @@
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
import android.security.keystore.UserNotAuthenticatedException;
+import android.security.recoverablekeystore.KeyEntryRecoveryData;
+import android.security.recoverablekeystore.KeyStoreRecoveryData;
+import android.security.recoverablekeystore.KeyStoreRecoveryMetadata;
+import android.security.recoverablekeystore.RecoverableKeyStoreLoader.RecoverableKeyStoreLoaderException;
import android.service.gatekeeper.GateKeeperResponse;
import android.service.gatekeeper.IGateKeeperService;
import android.text.TextUtils;
@@ -95,9 +102,10 @@
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.server.SystemService;
import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
+import com.android.server.locksettings.LockSettingsStorage.PersistentData;
+import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
-import com.android.server.locksettings.LockSettingsStorage.PersistentData;
import libcore.util.HexEncoding;
@@ -169,6 +177,8 @@
private final KeyStore mKeyStore;
+ private final RecoverableKeyStoreManager mRecoverableKeyStoreManager;
+
private boolean mFirstCallToVold;
protected IGateKeeperService mGateKeeperService;
@@ -367,6 +377,10 @@
return KeyStore.getInstance();
}
+ public RecoverableKeyStoreManager getRecoverableKeyStoreManager() {
+ return RecoverableKeyStoreManager.getInstance(mContext);
+ }
+
public IStorageManager getStorageManager() {
final IBinder service = ServiceManager.getService("mount");
if (service != null) {
@@ -393,6 +407,7 @@
mInjector = injector;
mContext = injector.getContext();
mKeyStore = injector.getKeyStore();
+ mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager();
mHandler = injector.getHandler();
mStrongAuth = injector.getStrongAuth();
mActivityManager = injector.getActivityManager();
@@ -1914,6 +1929,72 @@
}
}
+ @Override
+ public void initRecoveryService(@NonNull String rootCertificateAlias,
+ @NonNull byte[] signedPublicKeyList, int userId)
+ throws RemoteException {
+ mRecoverableKeyStoreManager.initRecoveryService(rootCertificateAlias,
+ signedPublicKeyList, userId);
+ }
+
+ @Override
+ public KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account, int userId)
+ throws RemoteException {
+ return mRecoverableKeyStoreManager.getRecoveryData(account, userId);
+ }
+
+ @Override
+ public void setServerParameters(long serverParameters, int userId) throws RemoteException {
+ mRecoverableKeyStoreManager.setServerParameters(serverParameters, userId);
+ }
+
+ @Override
+ public void setRecoveryStatus(@NonNull String packageName, @Nullable String[] aliases,
+ int status, int userId) throws RemoteException {
+ mRecoverableKeyStoreManager.setRecoveryStatus(packageName, aliases, status, userId);
+ }
+
+ @Override
+ public void setRecoverySecretTypes(@NonNull @KeyStoreRecoveryMetadata.UserSecretType
+ int[] secretTypes, int userId) throws RemoteException {
+ mRecoverableKeyStoreManager.setRecoverySecretTypes(secretTypes, userId);
+ }
+
+ @Override
+ public int[] getRecoverySecretTypes(int userId) throws RemoteException {
+ return mRecoverableKeyStoreManager.getRecoverySecretTypes(userId);
+
+ }
+
+ @Override
+ public int[] getPendingRecoverySecretTypes(int userId) throws RemoteException {
+ throw new SecurityException("Not implemented");
+ }
+
+ @Override
+ public void recoverySecretAvailable(@NonNull KeyStoreRecoveryMetadata recoverySecret,
+ int userId)
+ throws RemoteException {
+ mRecoverableKeyStoreManager.recoverySecretAvailable(recoverySecret, userId);
+ }
+
+ @Override
+ public byte[] startRecoverySession(@NonNull String sessionId,
+ @NonNull byte[] verifierPublicKey, @NonNull byte[] vaultParams,
+ @NonNull byte[] vaultChallenge, @NonNull List<KeyStoreRecoveryMetadata> secrets,
+ int userId) throws RemoteException {
+ return mRecoverableKeyStoreManager.startRecoverySession(sessionId, verifierPublicKey,
+ vaultParams, vaultChallenge, secrets, userId);
+ }
+
+ @Override
+ public void recoverKeys(@NonNull String sessionId, @NonNull byte[] recoveryKeyBlob,
+ @NonNull List<KeyEntryRecoveryData> applicationKeys, int userId)
+ throws RemoteException {
+ mRecoverableKeyStoreManager.recoverKeys(sessionId, recoveryKeyBlob, applicationKeys,
+ userId);
+ }
+
private static final String[] VALID_SETTINGS = new String[] {
LockPatternUtils.LOCKOUT_PERMANENT_KEY,
LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/InsecureUserException.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/InsecureUserException.java
new file mode 100644
index 0000000..5155a99
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/InsecureUserException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.locksettings.recoverablekeystore;
+
+/**
+ * Error thrown initializing {@link PlatformKeyManager} if the user is not secure (i.e., has no
+ * lock screen set).
+ */
+public class InsecureUserException extends Exception {
+
+ /**
+ * A new instance with {@code message} error message.
+ */
+ public InsecureUserException(String message) {
+ super(message);
+ }
+}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxy.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxy.java
new file mode 100644
index 0000000..7c9b395
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxy.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.locksettings.recoverablekeystore;
+
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+
+/**
+ * Proxies {@link java.security.KeyStore}. As all of its methods are final, it cannot otherwise be
+ * mocked for tests.
+ *
+ * @hide
+ */
+public interface KeyStoreProxy {
+
+ /** @see KeyStore#containsAlias(String) */
+ boolean containsAlias(String alias) throws KeyStoreException;
+
+ /** @see KeyStore#getKey(String, char[]) */
+ Key getKey(String alias, char[] password)
+ throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException;
+
+ /** @see KeyStore#setEntry(String, KeyStore.Entry, KeyStore.ProtectionParameter) */
+ void setEntry(String alias, KeyStore.Entry entry, KeyStore.ProtectionParameter protParam)
+ throws KeyStoreException;
+}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxyImpl.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxyImpl.java
new file mode 100644
index 0000000..ceee381
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxyImpl.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.locksettings.recoverablekeystore;
+
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+
+/**
+ * Implementation of {@link KeyStoreProxy} that delegates all method calls to the {@link KeyStore}.
+ */
+public class KeyStoreProxyImpl implements KeyStoreProxy {
+
+ private final KeyStore mKeyStore;
+
+ /**
+ * A new instance, delegating to {@code keyStore}.
+ */
+ public KeyStoreProxyImpl(KeyStore keyStore) {
+ mKeyStore = keyStore;
+ }
+
+ @Override
+ public boolean containsAlias(String alias) throws KeyStoreException {
+ return mKeyStore.containsAlias(alias);
+ }
+
+ @Override
+ public Key getKey(String alias, char[] password)
+ throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
+ return mKeyStore.getKey(alias, password);
+ }
+
+ @Override
+ public void setEntry(String alias, KeyStore.Entry entry, KeyStore.ProtectionParameter protParam)
+ throws KeyStoreException {
+ mKeyStore.setEntry(alias, entry, protParam);
+ }
+}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java
new file mode 100644
index 0000000..38f5b45
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.locksettings.recoverablekeystore;
+
+import android.security.keystore.AndroidKeyStoreSecretKey;
+
+/**
+ * Private key stored in AndroidKeyStore. Used to wrap recoverable keys before writing them to disk.
+ *
+ * <p>Identified by a generation ID, which increments whenever a new platform key is generated. A
+ * new key must be generated whenever the user disables their lock screen, as the decryption key is
+ * tied to lock-screen authentication.
+ *
+ * <p>One current platform key exists per profile on the device. (As each must be tied to a
+ * different user's lock screen.)
+ *
+ * @hide
+ */
+public class PlatformEncryptionKey {
+
+ private final int mGenerationId;
+ private final AndroidKeyStoreSecretKey mKey;
+
+ /**
+ * A new instance.
+ *
+ * @param generationId The generation ID of the key.
+ * @param key The secret key handle. Can be used to encrypt WITHOUT requiring screen unlock.
+ */
+ public PlatformEncryptionKey(int generationId, AndroidKeyStoreSecretKey key) {
+ mGenerationId = generationId;
+ mKey = key;
+ }
+
+ /**
+ * Returns the generation ID of the key.
+ */
+ public int getGenerationId() {
+ return mGenerationId;
+ }
+
+ /**
+ * Returns the actual key, which can only be used to encrypt.
+ */
+ public AndroidKeyStoreSecretKey getKey() {
+ return mKey;
+ }
+}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
new file mode 100644
index 0000000..074c596
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.locksettings.recoverablekeystore;
+
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Environment;
+import android.security.keystore.AndroidKeyStoreSecretKey;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Locale;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.security.auth.DestroyFailedException;
+
+/**
+ * Manages creating and checking the validity of the platform key.
+ *
+ * <p>The platform key is used to wrap the material of recoverable keys before persisting them to
+ * disk. It is also used to decrypt the same keys on a screen unlock, before re-wrapping them with
+ * a recovery key and syncing them with remote storage.
+ *
+ * <p>Each platform key has two entries in AndroidKeyStore:
+ *
+ * <ul>
+ * <li>Encrypt entry - this entry enables the root user to at any time encrypt.
+ * <li>Decrypt entry - this entry enables the root user to decrypt only after recent user
+ * authentication, i.e., within 15 seconds after a screen unlock.
+ * </ul>
+ *
+ * <p>Both entries are enabled only for AES/GCM/NoPadding Cipher algorithm.
+ *
+ * @hide
+ */
+public class PlatformKeyManager {
+ private static final String TAG = "PlatformKeyManager";
+
+ private static final String KEY_ALGORITHM = "AES";
+ private static final int KEY_SIZE_BITS = 256;
+ private static final String SHARED_PREFS_KEY_GENERATION_ID = "generationId";
+ private static final String SHARED_PREFS_PATH = "/system/recoverablekeystore/platform_keys.xml";
+ private static final String KEY_ALIAS_PREFIX =
+ "com.android.server.locksettings.recoverablekeystore/platform/";
+ private static final String ENCRYPT_KEY_ALIAS_SUFFIX = "encrypt";
+ private static final String DECRYPT_KEY_ALIAS_SUFFIX = "decrypt";
+ private static final int USER_AUTHENTICATION_VALIDITY_DURATION_SECONDS = 15;
+
+ private final Context mContext;
+ private final KeyStoreProxy mKeyStore;
+ private final SharedPreferences mSharedPreferences;
+ private final int mUserId;
+
+ private static final String ANDROID_KEY_STORE_PROVIDER = "AndroidKeyStore";
+
+ /**
+ * A new instance operating on behalf of {@code userId}, storing its prefs in the location
+ * defined by {@code context}.
+ *
+ * @param context This should be the context of the RecoverableKeyStoreLoader service.
+ * @param userId The ID of the user to whose lock screen the platform key must be bound.
+ * @throws KeyStoreException if failed to initialize AndroidKeyStore.
+ * @throws NoSuchAlgorithmException if AES is unavailable - should never happen.
+ * @throws InsecureUserException if the user does not have a lock screen set.
+ * @throws SecurityException if the caller does not have permission to write to /data/system.
+ *
+ * @hide
+ */
+ public static PlatformKeyManager getInstance(Context context, int userId)
+ throws KeyStoreException, NoSuchAlgorithmException, InsecureUserException {
+ context = context.getApplicationContext();
+ File sharedPreferencesFile = new File(
+ Environment.getDataDirectory().getAbsoluteFile(), SHARED_PREFS_PATH);
+ sharedPreferencesFile.mkdirs();
+ PlatformKeyManager keyManager = new PlatformKeyManager(
+ userId,
+ context,
+ new KeyStoreProxyImpl(getAndLoadAndroidKeyStore()),
+ context.getSharedPreferences(sharedPreferencesFile, Context.MODE_PRIVATE));
+ keyManager.init();
+ return keyManager;
+ }
+
+ @VisibleForTesting
+ PlatformKeyManager(
+ int userId,
+ Context context,
+ KeyStoreProxy keyStore,
+ SharedPreferences sharedPreferences) {
+ mUserId = userId;
+ mKeyStore = keyStore;
+ mContext = context;
+ mSharedPreferences = sharedPreferences;
+ }
+
+ /**
+ * Returns the current generation ID of the platform key. This increments whenever a platform
+ * key has to be replaced. (e.g., because the user has removed and then re-added their lock
+ * screen).
+ *
+ * @hide
+ */
+ public int getGenerationId() {
+ return mSharedPreferences.getInt(getGenerationIdKey(), 1);
+ }
+
+ /**
+ * Returns {@code true} if the platform key is available. A platform key won't be available if
+ * the user has not set up a lock screen.
+ *
+ * @hide
+ */
+ public boolean isAvailable() {
+ return mContext.getSystemService(KeyguardManager.class).isDeviceSecure(mUserId);
+ }
+
+ /**
+ * Generates a new key and increments the generation ID. Should be invoked if the platform key
+ * is corrupted and needs to be rotated.
+ *
+ * @throws NoSuchAlgorithmException if AES is unavailable - should never happen.
+ * @throws KeyStoreException if there is an error in AndroidKeyStore.
+ *
+ * @hide
+ */
+ public void regenerate() throws NoSuchAlgorithmException, KeyStoreException {
+ int generationId = getGenerationId();
+ generateAndLoadKey(generationId + 1);
+ setGenerationId(generationId + 1);
+ }
+
+ /**
+ * Returns the platform key used for encryption.
+ *
+ * @throws KeyStoreException if there was an AndroidKeyStore error.
+ * @throws UnrecoverableKeyException if the key could not be recovered.
+ * @throws NoSuchAlgorithmException if AES is unavailable - should never occur.
+ *
+ * @hide
+ */
+ public PlatformEncryptionKey getEncryptKey()
+ throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException {
+ int generationId = getGenerationId();
+ AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
+ getEncryptAlias(generationId), /*password=*/ null);
+ return new PlatformEncryptionKey(generationId, key);
+ }
+
+ /**
+ * Returns the platform key used for decryption. Only works after a recent screen unlock.
+ *
+ * @throws KeyStoreException if there was an AndroidKeyStore error.
+ * @throws UnrecoverableKeyException if the key could not be recovered.
+ * @throws NoSuchAlgorithmException if AES is unavailable - should never occur.
+ *
+ * @hide
+ */
+ public PlatformDecryptionKey getDecryptKey()
+ throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException {
+ int generationId = getGenerationId();
+ AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
+ getDecryptAlias(generationId), /*password=*/ null);
+ return new PlatformDecryptionKey(generationId, key);
+ }
+
+ /**
+ * Initializes the class. If there is no current platform key, and the user has a lock screen
+ * set, will create the platform key and set the generation ID.
+ *
+ * @throws KeyStoreException if there was an error in AndroidKeyStore.
+ * @throws NoSuchAlgorithmException if AES is unavailable - should never happen.
+ *
+ * @hide
+ */
+ public void init() throws KeyStoreException, NoSuchAlgorithmException, InsecureUserException {
+ if (!isAvailable()) {
+ throw new InsecureUserException(String.format(
+ Locale.US, "%d does not have a lock screen set.", mUserId));
+ }
+
+ int generationId = getGenerationId();
+ if (isKeyLoaded(generationId)) {
+ Log.i(TAG, String.format(
+ Locale.US, "Platform key generation %d exists already.", generationId));
+ return;
+ }
+ if (generationId == 1) {
+ Log.i(TAG, "Generating initial platform ID.");
+ } else {
+ Log.w(TAG, String.format(Locale.US, "Platform generation ID was %d but no "
+ + "entry was present in AndroidKeyStore. Generating fresh key.", generationId));
+ }
+
+ generateAndLoadKey(generationId);
+ }
+
+ /**
+ * Returns the alias of the encryption key with the specific {@code generationId} in the
+ * AndroidKeyStore.
+ *
+ * <p>These IDs look as follows:
+ * {@code com.security.recoverablekeystore/platform/<user id>/<generation id>/encrypt}
+ *
+ * @param generationId The generation ID.
+ * @return The alias.
+ */
+ private String getEncryptAlias(int generationId) {
+ return KEY_ALIAS_PREFIX + mUserId + "/" + generationId + "/" + ENCRYPT_KEY_ALIAS_SUFFIX;
+ }
+
+ /**
+ * Returns the alias of the decryption key with the specific {@code generationId} in the
+ * AndroidKeyStore.
+ *
+ * <p>These IDs look as follows:
+ * {@code com.security.recoverablekeystore/platform/<user id>/<generation id>/decrypt}
+ *
+ * @param generationId The generation ID.
+ * @return The alias.
+ */
+ private String getDecryptAlias(int generationId) {
+ return KEY_ALIAS_PREFIX + mUserId + "/" + generationId + "/" + DECRYPT_KEY_ALIAS_SUFFIX;
+ }
+
+ /**
+ * Sets the current generation ID to {@code generationId}.
+ */
+ private void setGenerationId(int generationId) {
+ mSharedPreferences.edit().putInt(getGenerationIdKey(), generationId).commit();
+ }
+
+ /**
+ * Returns the current user's generation ID key in the shared preferences.
+ */
+ private String getGenerationIdKey() {
+ return SHARED_PREFS_KEY_GENERATION_ID + "/" + mUserId;
+ }
+
+ /**
+ * Returns {@code true} if a key has been loaded with the given {@code generationId} into
+ * AndroidKeyStore.
+ *
+ * @throws KeyStoreException if there was an error checking AndroidKeyStore.
+ */
+ private boolean isKeyLoaded(int generationId) throws KeyStoreException {
+ return mKeyStore.containsAlias(getEncryptAlias(generationId))
+ && mKeyStore.containsAlias(getDecryptAlias(generationId));
+ }
+
+ /**
+ * Generates a new 256-bit AES key, and loads it into AndroidKeyStore with the given
+ * {@code generationId} determining its aliases.
+ *
+ * @throws NoSuchAlgorithmException if AES is unavailable. This should never happen, as it is
+ * available since API version 1.
+ * @throws KeyStoreException if there was an issue loading the keys into AndroidKeyStore.
+ */
+ private void generateAndLoadKey(int generationId)
+ throws NoSuchAlgorithmException, KeyStoreException {
+ String encryptAlias = getEncryptAlias(generationId);
+ String decryptAlias = getDecryptAlias(generationId);
+ SecretKey secretKey = generateAesKey();
+
+ mKeyStore.setEntry(
+ encryptAlias,
+ new KeyStore.SecretKeyEntry(secretKey),
+ new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+ .build());
+ mKeyStore.setEntry(
+ decryptAlias,
+ new KeyStore.SecretKeyEntry(secretKey),
+ new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
+ .setUserAuthenticationRequired(true)
+ .setUserAuthenticationValidityDurationSeconds(
+ USER_AUTHENTICATION_VALIDITY_DURATION_SECONDS)
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+ .setBoundToSpecificSecureUserId(mUserId)
+ .build());
+
+ try {
+ secretKey.destroy();
+ } catch (DestroyFailedException e) {
+ Log.w(TAG, "Failed to destroy in-memory platform key.", e);
+ }
+ }
+
+ /**
+ * Generates a new 256-bit AES key, in software.
+ *
+ * @return The software-generated AES key.
+ * @throws NoSuchAlgorithmException if AES key generation is not available. This should never
+ * happen, as AES has been supported since API level 1.
+ */
+ private static SecretKey generateAesKey() throws NoSuchAlgorithmException {
+ KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
+ keyGenerator.init(KEY_SIZE_BITS);
+ return keyGenerator.generateKey();
+ }
+
+ /**
+ * Returns AndroidKeyStore-provided {@link KeyStore}, having already invoked
+ * {@link KeyStore#load(KeyStore.LoadStoreParameter)}.
+ *
+ * @throws KeyStoreException if there was a problem getting or initializing the key store.
+ */
+ private static KeyStore getAndLoadAndroidKeyStore() throws KeyStoreException {
+ KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_PROVIDER);
+ try {
+ keyStore.load(/*param=*/ null);
+ } catch (CertificateException | IOException | NoSuchAlgorithmException e) {
+ // Should never happen.
+ throw new KeyStoreException("Unable to load keystore.", e);
+ }
+ return keyStore;
+ }
+}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java
index 40c7889..54deec2 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java
@@ -56,7 +56,7 @@
* @hide
*/
public static RecoverableKeyGenerator newInstance(
- AndroidKeyStoreSecretKey platformKey, RecoverableKeyStorage recoverableKeyStorage)
+ PlatformEncryptionKey platformKey, RecoverableKeyStorage recoverableKeyStorage)
throws NoSuchAlgorithmException {
// NB: This cannot use AndroidKeyStore as the provider, as we need access to the raw key
// material, so that it can be synced to disk in encrypted form.
@@ -66,11 +66,11 @@
private final KeyGenerator mKeyGenerator;
private final RecoverableKeyStorage mRecoverableKeyStorage;
- private final AndroidKeyStoreSecretKey mPlatformKey;
+ private final PlatformEncryptionKey mPlatformKey;
private RecoverableKeyGenerator(
KeyGenerator keyGenerator,
- AndroidKeyStoreSecretKey platformKey,
+ PlatformEncryptionKey platformKey,
RecoverableKeyStorage recoverableKeyStorage) {
mKeyGenerator = keyGenerator;
mRecoverableKeyStorage = recoverableKeyStorage;
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
new file mode 100644
index 0000000..e459f28
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.locksettings.recoverablekeystore;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.os.UserHandle;
+
+import android.security.recoverablekeystore.KeyEntryRecoveryData;
+import android.security.recoverablekeystore.KeyStoreRecoveryData;
+import android.security.recoverablekeystore.KeyStoreRecoveryMetadata;
+import android.security.recoverablekeystore.RecoverableKeyStoreLoader;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class with {@link RecoverableKeyStoreLoader} API implementation and internal methods to interact
+ * with {@code LockSettingsService}.
+ *
+ * @hide
+ */
+public class RecoverableKeyStoreManager {
+ private static final String TAG = "RecoverableKeyStoreManager";
+
+ private static RecoverableKeyStoreManager mInstance;
+ private Context mContext;
+
+ /**
+ * Returns a new or existing instance.
+ *
+ * @hide
+ */
+ public static synchronized RecoverableKeyStoreManager getInstance(Context mContext) {
+ if (mInstance == null) {
+ mInstance = new RecoverableKeyStoreManager(mContext);
+ }
+ return mInstance;
+ }
+
+ @VisibleForTesting
+ RecoverableKeyStoreManager(Context context) {
+ mContext = context;
+ }
+
+ public int initRecoveryService(
+ @NonNull String rootCertificateAlias, @NonNull byte[] signedPublicKeyList, int userId)
+ throws RemoteException {
+ checkRecoverKeyStorePermission();
+ // TODO open /system/etc/security/... cert file
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Gets all data necessary to recover application keys on new device.
+ *
+ * @return recovery data
+ * @hide
+ */
+ public KeyStoreRecoveryData getRecoveryData(@NonNull byte[] account, int userId)
+ throws RemoteException {
+ checkRecoverKeyStorePermission();
+ final int callingUid = Binder.getCallingUid(); // Recovery agent uid.
+ final int callingUserId = UserHandle.getCallingUserId();
+ final long callingIdentiy = Binder.clearCallingIdentity();
+ try {
+ // TODO: Return the latest snapshot for the calling recovery agent.
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentiy);
+ }
+
+ // KeyStoreRecoveryData without application keys and empty recovery blob.
+ KeyStoreRecoveryData recoveryData =
+ new KeyStoreRecoveryData(
+ /*snapshotVersion=*/ 1,
+ new ArrayList<KeyStoreRecoveryMetadata>(),
+ new ArrayList<KeyEntryRecoveryData>(),
+ /*encryptedRecoveryKeyBlob=*/ new byte[] {});
+ throw new ServiceSpecificException(
+ RecoverableKeyStoreLoader.UNINITIALIZED_RECOVERY_PUBLIC_KEY);
+ }
+
+ public void setServerParameters(long serverParameters, int userId) throws RemoteException {
+ checkRecoverKeyStorePermission();
+ throw new UnsupportedOperationException();
+ }
+
+ public void setRecoveryStatus(
+ @NonNull String packageName, @Nullable String[] aliases, int status, int userId)
+ throws RemoteException {
+ checkRecoverKeyStorePermission();
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Sets recovery secrets list used by all recovery agents for given {@code userId}
+ *
+ * @hide
+ */
+ public void setRecoverySecretTypes(
+ @NonNull @KeyStoreRecoveryMetadata.UserSecretType int[] secretTypes, int userId)
+ throws RemoteException {
+ checkRecoverKeyStorePermission();
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Gets secret types necessary to create Recovery Data.
+ *
+ * @return secret types
+ * @hide
+ */
+ public int[] getRecoverySecretTypes(int userId) throws RemoteException {
+ checkRecoverKeyStorePermission();
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Gets secret types RecoverableKeyStoreLoaders is waiting for to create new Recovery Data.
+ *
+ * @return secret types
+ * @hide
+ */
+ public int[] getPendingRecoverySecretTypes(int userId) throws RemoteException {
+ checkRecoverKeyStorePermission();
+ throw new UnsupportedOperationException();
+ }
+
+ public void recoverySecretAvailable(
+ @NonNull KeyStoreRecoveryMetadata recoverySecret, int userId) throws RemoteException {
+ final int callingUid = Binder.getCallingUid(); // Recovery agent uid.
+ if (recoverySecret.getLockScreenUiFormat() == KeyStoreRecoveryMetadata.TYPE_LOCKSCREEN) {
+ throw new SecurityException(
+ "Caller " + callingUid + "is not allowed to set lock screen secret");
+ }
+ checkRecoverKeyStorePermission();
+ // TODO: add hook from LockSettingsService to set lock screen secret.
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Initializes recovery session.
+ *
+ * @return recovery claim
+ * @hide
+ */
+ public byte[] startRecoverySession(
+ @NonNull String sessionId,
+ @NonNull byte[] verifierPublicKey,
+ @NonNull byte[] vaultParams,
+ @NonNull byte[] vaultChallenge,
+ @NonNull List<KeyStoreRecoveryMetadata> secrets,
+ int userId)
+ throws RemoteException {
+ checkRecoverKeyStorePermission();
+ throw new UnsupportedOperationException();
+ }
+
+ public void recoverKeys(
+ @NonNull String sessionId,
+ @NonNull byte[] recoveryKeyBlob,
+ @NonNull List<KeyEntryRecoveryData> applicationKeys,
+ int userId)
+ throws RemoteException {
+ checkRecoverKeyStorePermission();
+ throw new UnsupportedOperationException();
+ }
+
+ /** This function can only be used inside LockSettingsService. */
+ public void lockScreenSecretAvailable(
+ @KeyStoreRecoveryMetadata.LockScreenUiFormat int type,
+ String unencryptedPassword,
+ int userId) {
+ // TODO: compute SHA256 or Argon2id depending on secret type.
+ throw new UnsupportedOperationException();
+ }
+
+ /** This function can only be used inside LockSettingsService. */
+ public void lockScreenSecretChanged(
+ @KeyStoreRecoveryMetadata.LockScreenUiFormat int type,
+ @Nullable String unencryptedPassword,
+ int userId) {
+ throw new UnsupportedOperationException();
+ }
+
+ private void checkRecoverKeyStorePermission() {
+ mContext.enforceCallingOrSelfPermission(
+ RecoverableKeyStoreLoader.PERMISSION_RECOVER_KEYSTORE,
+ "Caller " + Binder.getCallingUid() + " doesn't have RecoverKeyStore permission.");
+ }
+}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java
index f18e796..dfa173c 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java
@@ -44,6 +44,7 @@
private static final String APPLICATION_KEY_ALGORITHM = "AES";
private static final int GCM_TAG_LENGTH_BITS = 128;
+ private final int mPlatformKeyGenerationId;
private final byte[] mNonce;
private final byte[] mKeyMaterial;
@@ -55,8 +56,8 @@
* {@link android.security.keystore.AndroidKeyStoreKey} for an example of a key that does
* not expose its key material.
*/
- public static WrappedKey fromSecretKey(
- SecretKey wrappingKey, SecretKey key) throws InvalidKeyException, KeyStoreException {
+ public static WrappedKey fromSecretKey(PlatformEncryptionKey wrappingKey, SecretKey key)
+ throws InvalidKeyException, KeyStoreException {
if (key.getEncoded() == null) {
throw new InvalidKeyException(
"key does not expose encoded material. It cannot be wrapped.");
@@ -70,7 +71,7 @@
"Android does not support AES/GCM/NoPadding. This should never happen.");
}
- cipher.init(Cipher.WRAP_MODE, wrappingKey);
+ cipher.init(Cipher.WRAP_MODE, wrappingKey.getKey());
byte[] encryptedKeyMaterial;
try {
encryptedKeyMaterial = cipher.wrap(key);
@@ -90,7 +91,10 @@
}
}
- return new WrappedKey(/*mNonce=*/ cipher.getIV(), /*mKeyMaterial=*/ encryptedKeyMaterial);
+ return new WrappedKey(
+ /*nonce=*/ cipher.getIV(),
+ /*keyMaterial=*/ encryptedKeyMaterial,
+ /*platformKeyGenerationId=*/ wrappingKey.getGenerationId());
}
/**
@@ -98,12 +102,14 @@
*
* @param nonce The nonce with which the key material was encrypted.
* @param keyMaterial The encrypted bytes of the key material.
+ * @param platformKeyGenerationId The generation ID of the key used to wrap this key.
*
* @hide
*/
- public WrappedKey(byte[] nonce, byte[] keyMaterial) {
+ public WrappedKey(byte[] nonce, byte[] keyMaterial, int platformKeyGenerationId) {
mNonce = nonce;
mKeyMaterial = keyMaterial;
+ mPlatformKeyGenerationId = platformKeyGenerationId;
}
/**
@@ -131,8 +137,7 @@
* @hide
*/
public int getPlatformKeyGenerationId() {
- // TODO(robertberry) Implement. See ag/3362855.
- return 1;
+ return mPlatformKeyGenerationId;
}
/**
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java
index 79bf5aa..7986533 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java
@@ -62,13 +62,12 @@
*
* @param uid Uid of the application to whom the key belongs.
* @param alias The alias of the key in the AndroidKeyStore.
- * @param wrappedKey The wrapped bytes of the key.
- * @param generationId The generation ID of the platform key that wrapped the key.
+ * @param wrappedKey The wrapped key.
* @return The primary key of the inserted row, or -1 if failed.
*
* @hide
*/
- public long insertKey(int uid, String alias, WrappedKey wrappedKey, int generationId) {
+ public long insertKey(int uid, String alias, WrappedKey wrappedKey) {
SQLiteDatabase db = mKeyStoreDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KeysEntry.COLUMN_NAME_UID, uid);
@@ -76,7 +75,7 @@
values.put(KeysEntry.COLUMN_NAME_NONCE, wrappedKey.getNonce());
values.put(KeysEntry.COLUMN_NAME_WRAPPED_KEY, wrappedKey.getKeyMaterial());
values.put(KeysEntry.COLUMN_NAME_LAST_SYNCED_AT, -1);
- values.put(KeysEntry.COLUMN_NAME_GENERATION_ID, generationId);
+ values.put(KeysEntry.COLUMN_NAME_GENERATION_ID, wrappedKey.getPlatformKeyGenerationId());
return db.replace(KeysEntry.TABLE_NAME, /*nullColumnHack=*/ null, values);
}
@@ -123,7 +122,9 @@
cursor.getColumnIndexOrThrow(KeysEntry.COLUMN_NAME_NONCE));
byte[] keyMaterial = cursor.getBlob(
cursor.getColumnIndexOrThrow(KeysEntry.COLUMN_NAME_WRAPPED_KEY));
- return new WrappedKey(nonce, keyMaterial);
+ int generationId = cursor.getInt(
+ cursor.getColumnIndexOrThrow(KeysEntry.COLUMN_NAME_GENERATION_ID));
+ return new WrappedKey(nonce, keyMaterial, generationId);
}
}
@@ -168,7 +169,7 @@
cursor.getColumnIndexOrThrow(KeysEntry.COLUMN_NAME_WRAPPED_KEY));
String alias = cursor.getString(
cursor.getColumnIndexOrThrow(KeysEntry.COLUMN_NAME_ALIAS));
- keys.put(alias, new WrappedKey(nonce, keyMaterial));
+ keys.put(alias, new WrappedKey(nonce, keyMaterial, platformKeyGenerationId));
}
return keys;
}
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 0b089fb..384efdd 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -21,6 +21,9 @@
import android.annotation.NonNull;
import android.app.ActivityManager;
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -96,21 +99,23 @@
private final ArrayMap<IBinder, ClientRecord> mAllClientRecords =
new ArrayMap<IBinder, ClientRecord>();
private int mCurrentUserId = -1;
- private boolean mGlobalBluetoothA2dpOn = false;
private final IAudioService mAudioService;
private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
private final Handler mHandler = new Handler();
- private final AudioRoutesInfo mAudioRoutesInfo = new AudioRoutesInfo();
private final IntArray mActivePlayerMinPriorityQueue = new IntArray();
private final IntArray mActivePlayerUidMinPriorityQueue = new IntArray();
+ private final BroadcastReceiver mReceiver = new MediaRouterServiceBroadcastReceiver();
+ BluetoothDevice mBluetoothDevice;
+ int mAudioRouteMainType = AudioRoutesInfo.MAIN_SPEAKER;
+ boolean mGlobalBluetoothA2dpOn = false;
+
public MediaRouterService(Context context) {
mContext = context;
Watchdog.getInstance().addMonitor(this);
mAudioService = IAudioService.Stub.asInterface(
ServiceManager.getService(Context.AUDIO_SERVICE));
-
mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance();
mAudioPlayerStateMonitor.registerListener(
new AudioPlayerStateMonitor.OnAudioPlayerActiveStateChangedListener() {
@@ -170,44 +175,30 @@
@Override
public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
synchronized (mLock) {
- if (newRoutes.mainType != mAudioRoutesInfo.mainType) {
+ if (newRoutes.mainType != mAudioRouteMainType) {
if ((newRoutes.mainType & (AudioRoutesInfo.MAIN_HEADSET
| AudioRoutesInfo.MAIN_HEADPHONES
| AudioRoutesInfo.MAIN_USB)) == 0) {
// headset was plugged out.
- mGlobalBluetoothA2dpOn = newRoutes.bluetoothName != null;
+ mGlobalBluetoothA2dpOn = mBluetoothDevice != null;
} else {
// headset was plugged in.
mGlobalBluetoothA2dpOn = false;
}
- mAudioRoutesInfo.mainType = newRoutes.mainType;
+ mAudioRouteMainType = newRoutes.mainType;
}
- if (!TextUtils.equals(
- newRoutes.bluetoothName, mAudioRoutesInfo.bluetoothName)) {
- if (newRoutes.bluetoothName == null) {
- // BT was disconnected.
- mGlobalBluetoothA2dpOn = false;
- } else {
- // BT was connected or changed.
- mGlobalBluetoothA2dpOn = true;
- }
- mAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName;
- }
- // Although a Bluetooth device is connected before a new audio playback is
- // started, dispatchAudioRoutChanged() can be called after
- // onAudioPlayerActiveStateChanged(). That causes restoreBluetoothA2dp()
- // is called before mGlobalBluetoothA2dpOn is updated.
- // Calling restoreBluetoothA2dp() here could prevent that.
- restoreBluetoothA2dp();
+ // The new audio routes info could be delivered with several seconds delay.
+ // In order to avoid such delay, Bluetooth device info will be updated
+ // via MediaRouterServiceBroadcastReceiver.
}
}
});
} catch (RemoteException e) {
Slog.w(TAG, "RemoteException in the audio service.");
}
- synchronized (mLock) {
- mGlobalBluetoothA2dpOn = (audioRoutes != null && audioRoutes.bluetoothName != null);
- }
+
+ IntentFilter intentFilter = new IntentFilter(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
+ context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
}
public void systemRunning() {
@@ -415,14 +406,12 @@
void restoreBluetoothA2dp() {
try {
- boolean btConnected = false;
boolean a2dpOn = false;
synchronized (mLock) {
- btConnected = mAudioRoutesInfo.bluetoothName != null;
a2dpOn = mGlobalBluetoothA2dpOn;
}
// We don't need to change a2dp status when bluetooth is not connected.
- if (btConnected) {
+ if (mBluetoothDevice != null) {
Slog.v(TAG, "restoreBluetoothA2dp(" + a2dpOn + ")");
mAudioService.setBluetoothA2dpOn(a2dpOn);
}
@@ -661,6 +650,25 @@
return false;
}
+ final class MediaRouterServiceBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
+ int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
+ BluetoothProfile.STATE_DISCONNECTED);
+ if (state == BluetoothProfile.STATE_DISCONNECTED) {
+ mGlobalBluetoothA2dpOn = false;
+ mBluetoothDevice = null;
+ } else if (state == BluetoothProfile.STATE_CONNECTED) {
+ mGlobalBluetoothA2dpOn = true;
+ mBluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ // To ensure that BT A2DP is on, call restoreBluetoothA2dp().
+ restoreBluetoothA2dp();
+ }
+ }
+ }
+ }
+
/**
* Information about a particular client of the media router.
* The contents of this object is guarded by mLock.
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 7b0ed0d..8e916ad 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -675,6 +675,7 @@
final SparseArray<Boolean> mUserRestorecon = new SparseArray<Boolean>();
int mCurrentUserId;
+ boolean mInAmbientMode;
static class WallpaperData {
@@ -953,6 +954,13 @@
}
mPaddingChanged = false;
}
+ if (mInfo != null && mInfo.getSupportsAmbientMode()) {
+ try {
+ mEngine.setInAmbientMode(mInAmbientMode);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to set ambient mode state", e);
+ }
+ }
try {
// This will trigger onComputeColors in the wallpaper engine.
// It's fine to be locked in here since the binder is oneway.
@@ -1743,6 +1751,28 @@
}
}
+ public void setInAmbientMode(boolean inAmbienMode) {
+ final IWallpaperEngine engine;
+ synchronized (mLock) {
+ mInAmbientMode = inAmbienMode;
+ final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
+ if (data != null && data.connection != null && data.connection.mInfo != null
+ && data.connection.mInfo.getSupportsAmbientMode()) {
+ engine = data.connection.mEngine;
+ } else {
+ engine = null;
+ }
+ }
+
+ if (engine != null) {
+ try {
+ engine.setInAmbientMode(inAmbienMode);
+ } catch (RemoteException e) {
+ // Cannot talk to wallpaper engine.
+ }
+ }
+ }
+
@Override
public boolean setLockWallpaperCallback(IWallpaperManagerCallback cb) {
checkPermission(android.Manifest.permission.INTERNAL_SYSTEM_WINDOW);
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index 39cc953..02ad6c7 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -101,7 +101,7 @@
return -1;
}
ALOGV("Registering callback...");
- set_wakeup_callback(&wakeup_callback);
+ autosuspend_set_wakeup_callback(&wakeup_callback);
}
// Wait for wakeup.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index 5b9e3a1..da42dc9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -15,6 +15,7 @@
*/
package com.android.server.devicepolicy;
+import android.annotation.UserIdInt;
import android.app.admin.IDevicePolicyManager;
import android.content.ComponentName;
import android.os.PersistableBundle;
@@ -24,6 +25,8 @@
import com.android.internal.R;
import com.android.server.SystemService;
+import java.util.List;
+
/**
* Defines the required interface for IDevicePolicyManager implemenation.
*
@@ -68,6 +71,23 @@
return false;
}
+ @Override
+ public boolean setPasswordBlacklist(ComponentName who, String name, List<String> blacklist,
+ boolean parent) {
+ return false;
+ }
+
+ @Override
+ public String getPasswordBlacklistName(ComponentName who, @UserIdInt int userId,
+ boolean parent) {
+ return null;
+ }
+
+ @Override
+ public boolean isPasswordBlacklisted(@UserIdInt int userId, String password) {
+ return false;
+ }
+
public boolean isUsingUnifiedPassword(ComponentName who) {
return true;
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index bead31f..d1a93d0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -734,6 +734,7 @@
private static final String TAG_PASSWORD_HISTORY_LENGTH = "password-history-length";
private static final String TAG_MIN_PASSWORD_LENGTH = "min-password-length";
private static final String ATTR_VALUE = "value";
+ private static final String TAG_PASSWORD_BLACKLIST = "password-blacklist";
private static final String TAG_PASSWORD_QUALITY = "password-quality";
private static final String TAG_POLICIES = "policies";
private static final String TAG_CROSS_PROFILE_WIDGET_PROVIDERS =
@@ -866,6 +867,9 @@
// Default title of confirm credentials screen
String organizationName = null;
+ // The blacklist data is stored in a file whose name is stored in the XML
+ String passwordBlacklistFile = null;
+
ActiveAdmin(DeviceAdminInfo _info, boolean parent) {
info = _info;
isParent = parent;
@@ -947,6 +951,11 @@
out.endTag(null, TAG_MIN_PASSWORD_NONLETTER);
}
}
+ if (passwordBlacklistFile != null) {
+ out.startTag(null, TAG_PASSWORD_BLACKLIST);
+ out.attribute(null, ATTR_VALUE, passwordBlacklistFile);
+ out.endTag(null, TAG_PASSWORD_BLACKLIST);
+ }
if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) {
out.startTag(null, TAG_MAX_TIME_TO_UNLOCK);
out.attribute(null, ATTR_VALUE, Long.toString(maximumTimeToUnlock));
@@ -1186,7 +1195,9 @@
} else if (TAG_MIN_PASSWORD_NONLETTER.equals(tag)) {
minimumPasswordMetrics.nonLetter = Integer.parseInt(
parser.getAttributeValue(null, ATTR_VALUE));
- } else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) {
+ } else if (TAG_PASSWORD_BLACKLIST.equals(tag)) {
+ passwordBlacklistFile = parser.getAttributeValue(null, ATTR_VALUE);
+ }else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) {
maximumTimeToUnlock = Long.parseLong(
parser.getAttributeValue(null, ATTR_VALUE));
} else if (TAG_STRONG_AUTH_UNLOCK_TIMEOUT.equals(tag)) {
@@ -1441,6 +1452,8 @@
pw.println(minimumPasswordMetrics.symbols);
pw.print(prefix); pw.print("minimumPasswordNonLetter=");
pw.println(minimumPasswordMetrics.nonLetter);
+ pw.print(prefix); pw.print("passwordBlacklist=");
+ pw.println(passwordBlacklistFile != null);
pw.print(prefix); pw.print("maximumTimeToUnlock=");
pw.println(maximumTimeToUnlock);
pw.print(prefix); pw.print("strongAuthUnlockTimeout=");
@@ -1693,6 +1706,10 @@
return new LockPatternUtils(mContext);
}
+ PasswordBlacklist newPasswordBlacklist(File file) {
+ return new PasswordBlacklist(file);
+ }
+
boolean storageManagerIsFileBasedEncryptionEnabled() {
return StorageManager.isFileEncryptedNativeOnly();
}
@@ -2589,11 +2606,15 @@
}
}
- private JournaledFile makeJournaledFile(int userHandle) {
- final String base = userHandle == UserHandle.USER_SYSTEM
- ? mInjector.getDevicePolicyFilePathForSystemUser() + DEVICE_POLICIES_XML
- : new File(mInjector.environmentGetUserSystemDirectory(userHandle),
- DEVICE_POLICIES_XML).getAbsolutePath();
+ private File getPolicyFileDirectory(@UserIdInt int userId) {
+ return userId == UserHandle.USER_SYSTEM
+ ? new File(mInjector.getDevicePolicyFilePathForSystemUser())
+ : mInjector.environmentGetUserSystemDirectory(userId);
+ }
+
+ private JournaledFile makeJournaledFile(@UserIdInt int userId) {
+ final String base = new File(getPolicyFileDirectory(userId), DEVICE_POLICIES_XML)
+ .getAbsolutePath();
if (VERBOSE_LOG) {
Log.v(LOG_TAG, "Opening " + base);
}
@@ -4064,6 +4085,136 @@
}
}
+ /* @return the password blacklist set by the admin or {@code null} if none. */
+ PasswordBlacklist getAdminPasswordBlacklistLocked(@NonNull ActiveAdmin admin) {
+ final int userId = UserHandle.getUserId(admin.getUid());
+ return admin.passwordBlacklistFile == null ? null : new PasswordBlacklist(
+ new File(getPolicyFileDirectory(userId), admin.passwordBlacklistFile));
+ }
+
+ private static final String PASSWORD_BLACKLIST_FILE_PREFIX = "password-blacklist-";
+ private static final String PASSWORD_BLACKLIST_FILE_SUFFIX = "";
+
+ @Override
+ public boolean setPasswordBlacklist(ComponentName who, String name, List<String> blacklist,
+ boolean parent) {
+ if (!mHasFeature) {
+ return false;
+ }
+ Preconditions.checkNotNull(who, "who is null");
+
+ synchronized (this) {
+ final ActiveAdmin admin = getActiveAdminForCallerLocked(
+ who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
+ final int userId = mInjector.userHandleGetCallingUserId();
+ PasswordBlacklist adminBlacklist = getAdminPasswordBlacklistLocked(admin);
+
+ if (blacklist == null || blacklist.isEmpty()) {
+ // Remove the adminBlacklist
+ admin.passwordBlacklistFile = null;
+ saveSettingsLocked(userId);
+ if (adminBlacklist != null) {
+ adminBlacklist.delete();
+ }
+ return true;
+ }
+
+ // Validate server side
+ Preconditions.checkNotNull(name, "name is null");
+ DevicePolicyManager.enforcePasswordBlacklistSize(blacklist);
+
+ // Blacklist is case insensitive so normalize to lower case
+ final int blacklistSize = blacklist.size();
+ for (int i = 0; i < blacklistSize; ++i) {
+ blacklist.set(i, blacklist.get(i).toLowerCase());
+ }
+
+ final boolean isNewBlacklist = adminBlacklist == null;
+ if (isNewBlacklist) {
+ // Create a new file for the blacklist. There could be multiple admins, each setting
+ // different blacklists, to restrict a user's credential, for example a managed
+ // profile can impose restrictions on its parent while the parent is already
+ // restricted by its own admin. A deterministic naming scheme would be fragile if
+ // new types of admin are introduced so we generate and save the file name instead.
+ // This isn't a temporary file but it reuses the name generation logic
+ final File file;
+ try {
+ file = File.createTempFile(PASSWORD_BLACKLIST_FILE_PREFIX,
+ PASSWORD_BLACKLIST_FILE_SUFFIX, getPolicyFileDirectory(userId));
+ } catch (IOException e) {
+ Slog.e(LOG_TAG, "Failed to make a file for the blacklist", e);
+ return false;
+ }
+ adminBlacklist = mInjector.newPasswordBlacklist(file);
+ }
+
+ if (adminBlacklist.savePasswordBlacklist(name, blacklist)) {
+ if (isNewBlacklist) {
+ // The blacklist was saved so point the admin to the file
+ admin.passwordBlacklistFile = adminBlacklist.getFile().getName();
+ saveSettingsLocked(userId);
+ }
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public String getPasswordBlacklistName(ComponentName who, @UserIdInt int userId,
+ boolean parent) {
+ if (!mHasFeature) {
+ return null;
+ }
+ Preconditions.checkNotNull(who, "who is null");
+ enforceFullCrossUsersPermission(userId);
+ synchronized (this) {
+ final ActiveAdmin admin = getActiveAdminForCallerLocked(
+ who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
+ final PasswordBlacklist blacklist = getAdminPasswordBlacklistLocked(admin);
+ if (blacklist == null) {
+ return null;
+ }
+ return blacklist.getName();
+ }
+ }
+
+ @Override
+ public boolean isPasswordBlacklisted(@UserIdInt int userId, String password) {
+ if (!mHasFeature) {
+ return false;
+ }
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.TEST_BLACKLISTED_PASSWORD, null);
+ return isPasswordBlacklistedInternal(userId, password);
+ }
+
+ private boolean isPasswordBlacklistedInternal(@UserIdInt int userId, String password) {
+ Preconditions.checkNotNull(password, "Password is null");
+ enforceFullCrossUsersPermission(userId);
+
+ // Normalize to lower case for case insensitive blacklist match
+ final String lowerCasePassword = password.toLowerCase();
+
+ synchronized (this) {
+ final List<ActiveAdmin> admins =
+ getActiveAdminsForLockscreenPoliciesLocked(userId, /* parent */ false);
+ final int N = admins.size();
+ for (int i = 0; i < N; i++) {
+ final PasswordBlacklist blacklist
+ = getAdminPasswordBlacklistLocked(admins.get(i));
+ if (blacklist != null) {
+ if (blacklist.isPasswordBlacklisted(lowerCasePassword)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
@Override
public boolean isActivePasswordSufficient(int userHandle, boolean parent) {
if (!mHasFeature) {
@@ -4420,6 +4571,11 @@
return false;
}
}
+
+ if (isPasswordBlacklistedInternal(userHandle, password)) {
+ Slog.w(LOG_TAG, "resetPassword: the password is blacklisted");
+ return false;
+ }
}
DevicePolicyData policy = getUserData(userHandle);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
index 4a6bee5..f91f959 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
@@ -29,10 +29,10 @@
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.TimeUnit;
/**
* A Handler class for managing network logging on a background thread.
@@ -81,6 +81,7 @@
}
};
+ @VisibleForTesting
static final int LOG_NETWORK_EVENT_MSG = 1;
/** Network events accumulated so far to be finalized into a batch at some point. */
@@ -106,9 +107,15 @@
private long mLastRetrievedBatchToken;
NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm) {
+ this(looper, dpm, 0 /* event id */);
+ }
+
+ @VisibleForTesting
+ NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm, long id) {
super(looper);
- mDpm = dpm;
- mAlarmManager = mDpm.mInjector.getAlarmManager();
+ this.mDpm = dpm;
+ this.mAlarmManager = mDpm.mInjector.getAlarmManager();
+ this.mId = id;
}
@Override
@@ -189,7 +196,13 @@
if (mNetworkEvents.size() > 0) {
// Assign ids to the events.
for (NetworkEvent event : mNetworkEvents) {
- event.setId(mId++);
+ event.setId(mId);
+ if (mId == Long.MAX_VALUE) {
+ Slog.i(TAG, "Reached maximum id value; wrapping around ." + mCurrentBatchToken);
+ mId = 0;
+ } else {
+ mId++;
+ }
}
// Finalize the batch and start a new one from scratch.
if (mBatches.size() >= MAX_BATCHES) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java b/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java
new file mode 100644
index 0000000..6a9b53a
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.devicepolicy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.AtomicFile;
+import android.util.Slog;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Manages the blacklisted passwords.
+ *
+ * This caller must ensure synchronized access.
+ */
+public class PasswordBlacklist {
+ private static final String TAG = "PasswordBlacklist";
+
+ private final AtomicFile mFile;
+
+ /**
+ * Create an object to manage the password blacklist.
+ *
+ * This is a lightweight operation to prepare variables but not perform any IO.
+ */
+ public PasswordBlacklist(File file) {
+ mFile = new AtomicFile(file);
+ }
+
+ /**
+ * Atomically replace the blacklist.
+ *
+ * Pass {@code null} for an empty list.
+ */
+ public boolean savePasswordBlacklist(@NonNull String name, @NonNull List<String> blacklist) {
+ FileOutputStream fos = null;
+ try {
+ fos = mFile.startWrite();
+ final DataOutputStream out = buildStreamForWriting(fos);
+ final Header header = new Header(Header.VERSION_1, name, blacklist.size());
+ header.write(out);
+ final int blacklistSize = blacklist.size();
+ for (int i = 0; i < blacklistSize; ++i) {
+ out.writeUTF(blacklist.get(i));
+ }
+ out.flush();
+ mFile.finishWrite(fos);
+ return true;
+ } catch (IOException e) {
+ mFile.failWrite(fos);
+ return false;
+ }
+ }
+
+ /** @return the name of the blacklist or {@code null} if none set. */
+ public String getName() {
+ try (DataInputStream in = openForReading()) {
+ return Header.read(in).mName;
+ } catch (IOException e) {
+ Slog.wtf(TAG, "Failed to read blacklist file", e);
+ }
+ return null;
+ }
+
+ /** @return the number of blacklisted passwords. */
+ public int getSize() {
+ final int blacklistSize;
+ try (DataInputStream in = openForReading()) {
+ return Header.read(in).mSize;
+ } catch (IOException e) {
+ Slog.wtf(TAG, "Failed to read blacklist file", e);
+ }
+ return 0;
+ }
+
+ /** @return whether the password matches an blacklisted item. */
+ public boolean isPasswordBlacklisted(@NonNull String password) {
+ final int blacklistSize;
+ try (DataInputStream in = openForReading()) {
+ final Header header = Header.read(in);
+ for (int i = 0; i < header.mSize; ++i) {
+ if (in.readUTF().equals(password)) {
+ return true;
+ }
+ }
+ } catch (IOException e) {
+ Slog.wtf(TAG, "Failed to read blacklist file", e);
+ // Fail safe and block all passwords. Setting a new blacklist should resolve this
+ // problem which can be identified by examining the log.
+ return true;
+ }
+ return false;
+ }
+
+ /** Delete the blacklist completely from disk. */
+ public void delete() {
+ mFile.delete();
+ }
+
+ /** Get the file the blacklist is stored in. */
+ public File getFile() {
+ return mFile.getBaseFile();
+ }
+
+ private DataOutputStream buildStreamForWriting(FileOutputStream fos) {
+ return new DataOutputStream(new BufferedOutputStream(fos));
+ }
+
+ private DataInputStream openForReading() throws IOException {
+ return new DataInputStream(new BufferedInputStream(mFile.openRead()));
+ }
+
+ /**
+ * Helper to read and write the header of the blacklist file.
+ */
+ private static class Header {
+ static final int VERSION_1 = 1;
+
+ final int mVersion; // File format version
+ final String mName;
+ final int mSize;
+
+ Header(int version, String name, int size) {
+ mVersion = version;
+ mName = name;
+ mSize = size;
+ }
+
+ void write(DataOutputStream out) throws IOException {
+ out.writeInt(mVersion);
+ out.writeUTF(mName);
+ out.writeInt(mSize);
+ }
+
+ static Header read(DataInputStream in) throws IOException {
+ final int version = in.readInt();
+ final String name = in.readUTF();
+ final int size = in.readInt();
+ return new Header(version, name, size);
+ }
+ }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 7aa628a..4310a98 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -26,6 +26,7 @@
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources.Theme;
+import android.database.sqlite.SQLiteCompatibilityWalFlags;
import android.os.BaseBundle;
import android.os.Binder;
import android.os.Build;
@@ -327,6 +328,8 @@
// The system server should never make non-oneway calls
Binder.setWarnOnBlocking(true);
+ // Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized
+ SQLiteCompatibilityWalFlags.init(null);
// Here we go!
Slog.i(TAG, "Entered the Android system server!");
@@ -803,6 +806,8 @@
traceBeginAndSlog("InstallSystemProviders");
mActivityManagerService.installSystemProviders();
+ // Now that SettingsProvider is ready, reactivate SQLiteCompatibilityWalFlags
+ SQLiteCompatibilityWalFlags.reset();
traceEnd();
traceBeginAndSlog("StartVibratorService");
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 d168479..0650acb 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -102,6 +102,11 @@
this.context = injector.context;
}
+ @Override
+ public boolean isPasswordBlacklisted(int userId, String password) {
+ return false;
+ }
+
public void notifyChangeToContentObserver(Uri uri, int userHandle) {
ContentObserver co = mMockInjector.mContentObservers.get(new Pair<>(uri, userHandle));
@@ -205,6 +210,11 @@
}
@Override
+ PasswordBlacklist newPasswordBlacklist(File file) {
+ return services.passwordBlacklist;
+ }
+
+ @Override
boolean storageManagerIsFileBasedEncryptionEnabled() {
return services.storageManager.isFileBasedEncryptionEnabled();
}
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 ca918c6..4779474 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -3765,6 +3765,36 @@
assertTrue(dpm.clearResetPasswordToken(admin1));
}
+ public void testSetPasswordBlacklistCannotBeCalledByNonAdmin() throws Exception {
+ assertExpectException(SecurityException.class, /* messageRegex= */ null,
+ () -> dpm.setPasswordBlacklist(admin1, null, null));
+ verifyZeroInteractions(getServices().passwordBlacklist);
+ }
+
+ public void testClearingPasswordBlacklistDoesNotCreateNewBlacklist() throws Exception {
+ setupProfileOwner();
+ dpm.setPasswordBlacklist(admin1, null, null);
+ verifyZeroInteractions(getServices().passwordBlacklist);
+ }
+
+ public void testSetPasswordBlacklistCreatesNewBlacklist() throws Exception {
+ final String name = "myblacklist";
+ final List<String> explicit = Arrays.asList("password", "letmein");
+ setupProfileOwner();
+ dpm.setPasswordBlacklist(admin1, name, explicit);
+ verify(getServices().passwordBlacklist).savePasswordBlacklist(name, explicit);
+ }
+
+ public void testSetPasswordBlacklistOnlyConvertsExplicitToLowerCase() throws Exception {
+ final List<String> mixedCase = Arrays.asList("password", "LETMEIN", "FooTBAll");
+ final List<String> lowerCase = Arrays.asList("password", "letmein", "football");
+ mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+ setupDeviceOwner();
+ final String name = "Name of the Blacklist";
+ dpm.setPasswordBlacklist(admin1, name, mixedCase);
+ verify(getServices().passwordBlacklist).savePasswordBlacklist(name, lowerCase);
+ }
+
public void testIsActivePasswordSufficient() throws Exception {
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
mContext.packageName = admin1.getPackageName();
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 4ee5ba6..8cb0459 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -86,6 +86,7 @@
public final IBackupManager ibackupManager;
public final IAudioService iaudioService;
public final LockPatternUtils lockPatternUtils;
+ public final PasswordBlacklist passwordBlacklist;
public final StorageManagerForMock storageManager;
public final WifiManager wifiManager;
public final SettingsForMock settings;
@@ -120,6 +121,7 @@
ibackupManager = mock(IBackupManager.class);
iaudioService = mock(IAudioService.class);
lockPatternUtils = mock(LockPatternUtils.class);
+ passwordBlacklist = mock(PasswordBlacklist.class);
storageManager = mock(StorageManagerForMock.class);
wifiManager = mock(WifiManager.class);
settings = mock(SettingsForMock.class);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java
index a92d1db..c698312 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java
@@ -15,13 +15,131 @@
*/
package com.android.server.devicepolicy;
+import static com.android.server.devicepolicy.NetworkLoggingHandler.LOG_NETWORK_EVENT_MSG;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
import android.app.admin.ConnectEvent;
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DnsEvent;
+import android.app.admin.NetworkEvent;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Message;
import android.os.Parcel;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+
+import org.mockito.ArgumentCaptor;
+
+import java.util.List;
+
@SmallTest
public class NetworkEventTest extends DpmTestBase {
+ private static final int MAX_EVENTS_PER_BATCH = 1200;
+
+ private DpmMockContext mSpiedDpmMockContext;
+ private DevicePolicyManagerServiceTestable mDpmTestable;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mSpiedDpmMockContext = spy(mMockContext);
+ mSpiedDpmMockContext.callerPermissions.add(
+ android.Manifest.permission.MANAGE_DEVICE_ADMINS);
+ doNothing().when(mSpiedDpmMockContext).sendBroadcastAsUser(any(Intent.class),
+ any(UserHandle.class));
+ LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
+ mDpmTestable = new DevicePolicyManagerServiceTestable(getServices(), mSpiedDpmMockContext);
+ setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
+ mDpmTestable.setActiveAdmin(admin1, true, DpmMockContext.CALLER_USER_HANDLE);
+ }
+
+ public void testNetworkEventId_monotonicallyIncreasing() throws Exception {
+ // GIVEN the handler has not processed any events.
+ long startingId = 0;
+
+ // WHEN the handler has processed the events.
+ List<NetworkEvent> events = fillHandlerWithFullBatchOfEvents(startingId);
+
+ // THEN the events are in a batch.
+ assertTrue("Batch not at the returned token.",
+ events != null && events.size() == MAX_EVENTS_PER_BATCH);
+ // THEN event ids are monotonically increasing.
+ long expectedId = startingId;
+ for (int i = 0; i < MAX_EVENTS_PER_BATCH; i++) {
+ assertEquals("At index " + i + ", the event has the wrong id.", expectedId,
+ events.get(i).getId());
+ expectedId++;
+ }
+ }
+
+ public void testNetworkEventId_wrapsAround() throws Exception {
+ // GIVEN the handler has almost processed Long.MAX_VALUE events.
+ int gap = 5;
+ long startingId = Long.MAX_VALUE - gap;
+
+ // WHEN the handler has processed the events.
+ List<NetworkEvent> events = fillHandlerWithFullBatchOfEvents(startingId);
+
+ // THEN the events are in a batch.
+ assertTrue("Batch not at the returned token.",
+ events != null && events.size() == MAX_EVENTS_PER_BATCH);
+ // THEN event ids are monotonically increasing.
+ long expectedId = startingId;
+ for (int i = 0; i < gap; i++) {
+ assertEquals("At index " + i + ", the event has the wrong id.", expectedId,
+ events.get(i).getId());
+ expectedId++;
+ }
+ // THEN event ids are reset when the id reaches the maximum possible value.
+ assertEquals("Event was not assigned the maximum id value.", Long.MAX_VALUE,
+ events.get(gap).getId());
+ assertEquals("Event id was not reset.", 0, events.get(gap + 1).getId());
+ // THEN event ids are monotonically increasing.
+ expectedId = 0;
+ for (int i = gap + 1; i < MAX_EVENTS_PER_BATCH; i++) {
+ assertEquals("At index " + i + ", the event has the wrong id.", expectedId,
+ events.get(i).getId());
+ expectedId++;
+ }
+ }
+
+ private List<NetworkEvent> fillHandlerWithFullBatchOfEvents(long startingId) throws Exception {
+ // GIVEN a handler with events
+ NetworkLoggingHandler handler = new NetworkLoggingHandler(new TestLooper().getLooper(),
+ mDpmTestable, startingId);
+ // GIVEN network events are sent to the handler.
+ for (int i = 0; i < MAX_EVENTS_PER_BATCH; i++) {
+ ConnectEvent event = new ConnectEvent("some_ip_address", 800, "com.google.foo",
+ SystemClock.currentThreadTimeMillis());
+ Message msg = new Message();
+ msg.what = LOG_NETWORK_EVENT_MSG;
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(NetworkLoggingHandler.NETWORK_EVENT_KEY, event);
+ msg.setData(bundle);
+ handler.handleMessage(msg);
+ }
+
+ // WHEN the handler processes the events.
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mSpiedDpmMockContext).sendBroadcastAsUser(intentCaptor.capture(),
+ any(UserHandle.class));
+ assertEquals(intentCaptor.getValue().getAction(),
+ DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE);
+ long token = intentCaptor.getValue().getExtras().getLong(
+ DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, 0);
+ return handler.retrieveFullLogBatch(token);
+ }
/**
* Test parceling and unparceling of a ConnectEvent.
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/PasswordBlacklistTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/PasswordBlacklistTest.java
new file mode 100644
index 0000000..1b3fc2c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/PasswordBlacklistTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.devicepolicy;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Unit tests for {@link PasswordBlacklist}.
+ *
+ * bit FrameworksServicesTests:com.android.server.devicepolicy.PasswordBlacklistTest
+ * runtest -x frameworks/base/services/tests/servicestests/src/com/android/server/devicepolicy/PasswordBlacklistTest.java
+ */
+@RunWith(AndroidJUnit4.class)
+public final class PasswordBlacklistTest {
+ private File mBlacklistFile;
+ private PasswordBlacklist mBlacklist;
+
+ @Before
+ public void setUp() throws IOException {
+ mBlacklistFile = File.createTempFile("pwdbl", null);
+ mBlacklist = new PasswordBlacklist(mBlacklistFile);
+ }
+
+ @After
+ public void tearDown() {
+ mBlacklist.delete();
+ }
+
+ @Test
+ public void matchIsExact() {
+ // Note: Case sensitivity is handled by the user of PasswordBlacklist by normalizing the
+ // values stored in and tested against it.
+ mBlacklist.savePasswordBlacklist("matchIsExact", Arrays.asList("password", "qWERty"));
+ assertTrue(mBlacklist.isPasswordBlacklisted("password"));
+ assertTrue(mBlacklist.isPasswordBlacklisted("qWERty"));
+ assertFalse(mBlacklist.isPasswordBlacklisted("Password"));
+ assertFalse(mBlacklist.isPasswordBlacklisted("qwert"));
+ assertFalse(mBlacklist.isPasswordBlacklisted("letmein"));
+ }
+
+ @Test
+ public void matchIsNotRegex() {
+ mBlacklist.savePasswordBlacklist("matchIsNotRegex", Arrays.asList("a+b*"));
+ assertTrue(mBlacklist.isPasswordBlacklisted("a+b*"));
+ assertFalse(mBlacklist.isPasswordBlacklisted("aaaa"));
+ assertFalse(mBlacklist.isPasswordBlacklisted("abbbb"));
+ assertFalse(mBlacklist.isPasswordBlacklisted("aaaa"));
+ }
+
+ @Test
+ public void matchFailsSafe() throws IOException {
+ try (FileOutputStream fos = new FileOutputStream(mBlacklistFile)) {
+ // Write a malformed blacklist file
+ fos.write(17);
+ }
+ assertTrue(mBlacklist.isPasswordBlacklisted("anything"));
+ assertTrue(mBlacklist.isPasswordBlacklisted("at"));
+ assertTrue(mBlacklist.isPasswordBlacklisted("ALL"));
+ }
+
+ @Test
+ public void blacklistCanBeNamed() {
+ final String name = "identifier";
+ mBlacklist.savePasswordBlacklist(name, Arrays.asList("one", "two", "three"));
+ assertEquals(mBlacklist.getName(), name);
+ }
+
+ @Test
+ public void reportsTheCorrectNumberOfEntries() {
+ mBlacklist.savePasswordBlacklist("Count Entries", Arrays.asList("1", "2", "3", "4"));
+ assertEquals(mBlacklist.getSize(), 4);
+ }
+
+ @Test
+ public void reportsBlacklistFile() {
+ assertEquals(mBlacklistFile, mBlacklist.getFile());
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
new file mode 100644
index 0000000..a997770
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.locksettings.recoverablekeystore;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.security.KeyStore;
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PlatformKeyManagerTest {
+
+ private static final int USER_AUTHENTICATION_VALIDITY_DURATION_SECONDS = 15;
+ private static final int USER_ID_FIXTURE = 42;
+ private static final String TEST_SHARED_PREFS_NAME = "PlatformKeyManagerTestPrefs";
+
+ @Mock private Context mContext;
+ @Mock private KeyStoreProxy mKeyStoreProxy;
+ @Mock private KeyguardManager mKeyguardManager;
+
+ @Captor private ArgumentCaptor<KeyStore.ProtectionParameter> mProtectionParameterCaptor;
+ @Captor private ArgumentCaptor<KeyStore.Entry> mEntryArgumentCaptor;
+
+ private SharedPreferences mSharedPreferences;
+ private PlatformKeyManager mPlatformKeyManager;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ Context testContext = InstrumentationRegistry.getTargetContext();
+ mSharedPreferences = testContext.getSharedPreferences(
+ TEST_SHARED_PREFS_NAME, Context.MODE_PRIVATE);
+ mPlatformKeyManager = new PlatformKeyManager(
+ USER_ID_FIXTURE, mContext, mKeyStoreProxy, mSharedPreferences);
+
+ when(mContext.getSystemService(anyString())).thenReturn(mKeyguardManager);
+ when(mContext.getSystemServiceName(any())).thenReturn("test");
+ when(mKeyguardManager.isDeviceSecure(USER_ID_FIXTURE)).thenReturn(true);
+ }
+
+ @After
+ public void tearDown() {
+ mSharedPreferences.edit().clear().commit();
+ }
+
+ @Test
+ public void init_createsEncryptKeyWithCorrectAlias() throws Exception {
+ mPlatformKeyManager.init();
+
+ verify(mKeyStoreProxy).setEntry(
+ eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/encrypt"),
+ any(),
+ any());
+ }
+
+ @Test
+ public void init_createsEncryptKeyWithCorrectPurposes() throws Exception {
+ mPlatformKeyManager.init();
+
+ assertEquals(KeyProperties.PURPOSE_ENCRYPT, getEncryptKeyProtection().getPurposes());
+ }
+
+ @Test
+ public void init_createsEncryptKeyWithCorrectPaddings() throws Exception {
+ mPlatformKeyManager.init();
+
+ assertArrayEquals(
+ new String[] { KeyProperties.ENCRYPTION_PADDING_NONE },
+ getEncryptKeyProtection().getEncryptionPaddings());
+ }
+
+ @Test
+ public void init_createsEncryptKeyWithCorrectBlockModes() throws Exception {
+ mPlatformKeyManager.init();
+
+ assertArrayEquals(
+ new String[] { KeyProperties.BLOCK_MODE_GCM },
+ getEncryptKeyProtection().getBlockModes());
+ }
+
+ @Test
+ public void init_createsEncryptKeyWithoutAuthenticationRequired() throws Exception {
+ mPlatformKeyManager.init();
+
+ assertFalse(getEncryptKeyProtection().isUserAuthenticationRequired());
+ }
+
+ @Test
+ public void init_createsDecryptKeyWithCorrectAlias() throws Exception {
+ mPlatformKeyManager.init();
+
+ verify(mKeyStoreProxy).setEntry(
+ eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/decrypt"),
+ any(),
+ any());
+ }
+
+ @Test
+ public void init_createsDecryptKeyWithCorrectPurposes() throws Exception {
+ mPlatformKeyManager.init();
+
+ assertEquals(KeyProperties.PURPOSE_DECRYPT, getDecryptKeyProtection().getPurposes());
+ }
+
+ @Test
+ public void init_createsDecryptKeyWithCorrectPaddings() throws Exception {
+ mPlatformKeyManager.init();
+
+ assertArrayEquals(
+ new String[] { KeyProperties.ENCRYPTION_PADDING_NONE },
+ getDecryptKeyProtection().getEncryptionPaddings());
+ }
+
+ @Test
+ public void init_createsDecryptKeyWithCorrectBlockModes() throws Exception {
+ mPlatformKeyManager.init();
+
+ assertArrayEquals(
+ new String[] { KeyProperties.BLOCK_MODE_GCM },
+ getDecryptKeyProtection().getBlockModes());
+ }
+
+ @Test
+ public void init_createsDecryptKeyWithAuthenticationRequired() throws Exception {
+ mPlatformKeyManager.init();
+
+ assertTrue(getDecryptKeyProtection().isUserAuthenticationRequired());
+ }
+
+ @Test
+ public void init_createsDecryptKeyWithAuthenticationValidFor15Seconds() throws Exception {
+ mPlatformKeyManager.init();
+
+ assertEquals(
+ USER_AUTHENTICATION_VALIDITY_DURATION_SECONDS,
+ getDecryptKeyProtection().getUserAuthenticationValidityDurationSeconds());
+ }
+
+ @Test
+ public void init_createsDecryptKeyBoundToTheUsersAuthentication() throws Exception {
+ mPlatformKeyManager.init();
+
+ assertEquals(
+ USER_ID_FIXTURE,
+ getDecryptKeyProtection().getBoundToSpecificSecureUserId());
+ }
+
+ @Test
+ public void init_createsBothKeysWithSameMaterial() throws Exception {
+ mPlatformKeyManager.init();
+
+ verify(mKeyStoreProxy, times(2)).setEntry(any(), mEntryArgumentCaptor.capture(), any());
+ List<KeyStore.Entry> entries = mEntryArgumentCaptor.getAllValues();
+ assertArrayEquals(
+ ((KeyStore.SecretKeyEntry) entries.get(0)).getSecretKey().getEncoded(),
+ ((KeyStore.SecretKeyEntry) entries.get(1)).getSecretKey().getEncoded());
+ }
+
+ @Test
+ public void init_setsGenerationIdTo1() throws Exception {
+ mPlatformKeyManager.init();
+
+ assertEquals(1, mPlatformKeyManager.getGenerationId());
+ }
+
+ @Test
+ public void getDecryptKey_getsDecryptKeyWithCorrectAlias() throws Exception {
+ mPlatformKeyManager.getDecryptKey();
+
+ verify(mKeyStoreProxy).getKey(
+ eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/decrypt"),
+ any());
+ }
+
+ @Test
+ public void getEncryptKey_getsDecryptKeyWithCorrectAlias() throws Exception {
+ mPlatformKeyManager.getEncryptKey();
+
+ verify(mKeyStoreProxy).getKey(
+ eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/encrypt"),
+ any());
+ }
+
+ @Test
+ public void regenerate_incrementsTheGenerationId() throws Exception {
+ mPlatformKeyManager.init();
+
+ mPlatformKeyManager.regenerate();
+
+ assertEquals(2, mPlatformKeyManager.getGenerationId());
+ }
+
+ @Test
+ public void regenerate_generatesANewEncryptKeyWithTheCorrectAlias() throws Exception {
+ mPlatformKeyManager.init();
+
+ mPlatformKeyManager.regenerate();
+
+ verify(mKeyStoreProxy).setEntry(
+ eq("com.android.server.locksettings.recoverablekeystore/platform/42/2/encrypt"),
+ any(),
+ any());
+ }
+
+ @Test
+ public void regenerate_generatesANewDecryptKeyWithTheCorrectAlias() throws Exception {
+ mPlatformKeyManager.init();
+
+ mPlatformKeyManager.regenerate();
+
+ verify(mKeyStoreProxy).setEntry(
+ eq("com.android.server.locksettings.recoverablekeystore/platform/42/2/decrypt"),
+ any(),
+ any());
+ }
+
+ private KeyProtection getEncryptKeyProtection() throws Exception {
+ verify(mKeyStoreProxy).setEntry(
+ eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/encrypt"),
+ any(),
+ mProtectionParameterCaptor.capture());
+ return (KeyProtection) mProtectionParameterCaptor.getValue();
+ }
+
+ private KeyProtection getDecryptKeyProtection() throws Exception {
+ verify(mKeyStoreProxy).setEntry(
+ eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/decrypt"),
+ any(),
+ mProtectionParameterCaptor.capture());
+ return (KeyProtection) mProtectionParameterCaptor.getValue();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java
index 298a988..12dbdb3 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java
@@ -48,6 +48,7 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class RecoverableKeyGeneratorTest {
+ private static final int TEST_GENERATION_ID = 3;
private static final String ANDROID_KEY_STORE_PROVIDER = "AndroidKeyStore";
private static final String KEY_ALGORITHM = "AES";
private static final String TEST_ALIAS = "karlin";
@@ -58,14 +59,14 @@
@Captor ArgumentCaptor<KeyProtection> mKeyProtectionArgumentCaptor;
- private AndroidKeyStoreSecretKey mPlatformKey;
+ private PlatformEncryptionKey mPlatformKey;
private SecretKey mKeyHandle;
private RecoverableKeyGenerator mRecoverableKeyGenerator;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mPlatformKey = generateAndroidKeyStoreKey();
+ mPlatformKey = new PlatformEncryptionKey(TEST_GENERATION_ID, generateAndroidKeyStoreKey());
mKeyHandle = generateKey();
mRecoverableKeyGenerator = RecoverableKeyGenerator.newInstance(
mPlatformKey, mRecoverableKeyStorage);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/WrappedKeyTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/WrappedKeyTest.java
index 8371fe5..56122a7 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/WrappedKeyTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/WrappedKeyTest.java
@@ -61,7 +61,8 @@
@Test
public void fromSecretKey_createsWrappedKeyThatCanBeUnwrapped() throws Exception {
- SecretKey wrappingKey = generateAndroidKeyStoreKey();
+ PlatformEncryptionKey wrappingKey = new PlatformEncryptionKey(
+ GENERATION_ID, generateAndroidKeyStoreKey());
SecretKey rawKey = generateKey();
WrappedKey wrappedKey = WrappedKey.fromSecretKey(wrappingKey, rawKey);
@@ -69,7 +70,7 @@
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(
Cipher.UNWRAP_MODE,
- wrappingKey,
+ wrappingKey.getKey(),
new GCMParameterSpec(GCM_TAG_LENGTH_BITS, wrappedKey.getNonce()));
SecretKey unwrappedKey = (SecretKey) cipher.unwrap(
wrappedKey.getKeyMaterial(), KEY_ALGORITHM, Cipher.SECRET_KEY);
@@ -77,15 +78,28 @@
}
@Test
+ public void fromSecretKey_returnsAKeyWithTheGenerationIdOfTheWrappingKey() throws Exception {
+ PlatformEncryptionKey wrappingKey = new PlatformEncryptionKey(
+ GENERATION_ID, generateAndroidKeyStoreKey());
+ SecretKey rawKey = generateKey();
+
+ WrappedKey wrappedKey = WrappedKey.fromSecretKey(wrappingKey, rawKey);
+
+ assertEquals(GENERATION_ID, wrappedKey.getPlatformKeyGenerationId());
+ }
+
+ @Test
public void decryptWrappedKeys_decryptsWrappedKeys() throws Exception {
String alias = "karlin";
- PlatformDecryptionKey platformKey = generatePlatformDecryptionKey();
+ AndroidKeyStoreSecretKey platformKey = generateAndroidKeyStoreKey();
SecretKey appKey = generateKey();
- WrappedKey wrappedKey = WrappedKey.fromSecretKey(platformKey.getKey(), appKey);
+ WrappedKey wrappedKey = WrappedKey.fromSecretKey(
+ new PlatformEncryptionKey(GENERATION_ID, platformKey), appKey);
HashMap<String, WrappedKey> keysByAlias = new HashMap<>();
keysByAlias.put(alias, wrappedKey);
- Map<String, SecretKey> unwrappedKeys = WrappedKey.unwrapKeys(platformKey, keysByAlias);
+ Map<String, SecretKey> unwrappedKeys = WrappedKey.unwrapKeys(
+ new PlatformDecryptionKey(GENERATION_ID, platformKey), keysByAlias);
assertEquals(1, unwrappedKeys.size());
assertTrue(unwrappedKeys.containsKey(alias));
@@ -95,26 +109,32 @@
@Test
public void decryptWrappedKeys_doesNotDieIfSomeKeysAreUnwrappable() throws Exception {
String alias = "karlin";
+ AndroidKeyStoreSecretKey platformKey = generateAndroidKeyStoreKey();
SecretKey appKey = generateKey();
- WrappedKey wrappedKey = WrappedKey.fromSecretKey(generateKey(), appKey);
+ WrappedKey wrappedKey = WrappedKey.fromSecretKey(
+ new PlatformEncryptionKey(GENERATION_ID, platformKey), appKey);
HashMap<String, WrappedKey> keysByAlias = new HashMap<>();
keysByAlias.put(alias, wrappedKey);
Map<String, SecretKey> unwrappedKeys = WrappedKey.unwrapKeys(
- generatePlatformDecryptionKey(), keysByAlias);
+ new PlatformDecryptionKey(GENERATION_ID, generateAndroidKeyStoreKey()),
+ keysByAlias);
assertEquals(0, unwrappedKeys.size());
}
@Test
public void decryptWrappedKeys_throwsIfPlatformKeyGenerationIdDoesNotMatch() throws Exception {
- WrappedKey wrappedKey = WrappedKey.fromSecretKey(generateKey(), generateKey());
+ AndroidKeyStoreSecretKey platformKey = generateAndroidKeyStoreKey();
+ WrappedKey wrappedKey = WrappedKey.fromSecretKey(
+ new PlatformEncryptionKey(GENERATION_ID, platformKey), generateKey());
HashMap<String, WrappedKey> keysByAlias = new HashMap<>();
keysByAlias.put("benji", wrappedKey);
try {
WrappedKey.unwrapKeys(
- generatePlatformDecryptionKey(/*generationId=*/ 2), keysByAlias);
+ new PlatformDecryptionKey(/*generationId=*/ 2, platformKey),
+ keysByAlias);
fail("Should have thrown.");
} catch (BadPlatformKeyException e) {
assertEquals(
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
index 5cb88dd..3d5b958 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
@@ -63,19 +63,23 @@
int userId = 12;
String alias = "test";
WrappedKey oldWrappedKey = new WrappedKey(
- getUtf8Bytes("nonce1"), getUtf8Bytes("keymaterial1"));
+ getUtf8Bytes("nonce1"),
+ getUtf8Bytes("keymaterial1"),
+ /*platformKeyGenerationId=*/1);
mRecoverableKeyStoreDb.insertKey(
- userId, alias, oldWrappedKey, /*generationId=*/ 1);
+ userId, alias, oldWrappedKey);
byte[] nonce = getUtf8Bytes("nonce2");
byte[] keyMaterial = getUtf8Bytes("keymaterial2");
- WrappedKey newWrappedKey = new WrappedKey(nonce, keyMaterial);
+ WrappedKey newWrappedKey = new WrappedKey(
+ nonce, keyMaterial, /*platformKeyGenerationId=*/2);
mRecoverableKeyStoreDb.insertKey(
- userId, alias, newWrappedKey, /*generationId=*/ 2);
+ userId, alias, newWrappedKey);
WrappedKey retrievedKey = mRecoverableKeyStoreDb.getKey(userId, alias);
assertArrayEquals(nonce, retrievedKey.getNonce());
assertArrayEquals(keyMaterial, retrievedKey.getKeyMaterial());
+ assertEquals(2, retrievedKey.getPlatformKeyGenerationId());
}
@Test
@@ -93,13 +97,14 @@
String alias = "test";
byte[] nonce = getUtf8Bytes("nonce");
byte[] keyMaterial = getUtf8Bytes("keymaterial");
- WrappedKey wrappedKey = new WrappedKey(nonce, keyMaterial);
- mRecoverableKeyStoreDb.insertKey(userId, alias, wrappedKey, generationId);
+ WrappedKey wrappedKey = new WrappedKey(nonce, keyMaterial, generationId);
+ mRecoverableKeyStoreDb.insertKey(userId, alias, wrappedKey);
WrappedKey retrievedKey = mRecoverableKeyStoreDb.getKey(userId, alias);
assertArrayEquals(nonce, retrievedKey.getNonce());
assertArrayEquals(keyMaterial, retrievedKey.getKeyMaterial());
+ assertEquals(generationId, retrievedKey.getPlatformKeyGenerationId());
}
@Test
@@ -109,8 +114,8 @@
String alias = "test";
byte[] nonce = getUtf8Bytes("nonce");
byte[] keyMaterial = getUtf8Bytes("keymaterial");
- WrappedKey wrappedKey = new WrappedKey(nonce, keyMaterial);
- mRecoverableKeyStoreDb.insertKey(userId, alias, wrappedKey, generationId);
+ WrappedKey wrappedKey = new WrappedKey(nonce, keyMaterial, generationId);
+ mRecoverableKeyStoreDb.insertKey(userId, alias, wrappedKey);
Map<String, WrappedKey> keys = mRecoverableKeyStoreDb.getAllKeys(userId, generationId);
@@ -119,15 +124,18 @@
WrappedKey retrievedKey = keys.get(alias);
assertArrayEquals(nonce, retrievedKey.getNonce());
assertArrayEquals(keyMaterial, retrievedKey.getKeyMaterial());
+ assertEquals(generationId, retrievedKey.getPlatformKeyGenerationId());
}
@Test
public void getAllKeys_doesNotReturnKeysWithBadGenerationId() {
int userId = 12;
WrappedKey wrappedKey = new WrappedKey(
- getUtf8Bytes("nonce"), getUtf8Bytes("keymaterial"));
+ getUtf8Bytes("nonce"),
+ getUtf8Bytes("keymaterial"),
+ /*platformKeyGenerationId=*/ 5);
mRecoverableKeyStoreDb.insertKey(
- userId, /*alias=*/ "test", wrappedKey, /*generationId=*/ 5);
+ userId, /*alias=*/ "test", wrappedKey);
Map<String, WrappedKey> keys = mRecoverableKeyStoreDb.getAllKeys(
userId, /*generationId=*/ 7);
@@ -139,9 +147,9 @@
public void getAllKeys_doesNotReturnKeysWithBadUserId() {
int generationId = 12;
WrappedKey wrappedKey = new WrappedKey(
- getUtf8Bytes("nonce"), getUtf8Bytes("keymaterial"));
+ getUtf8Bytes("nonce"), getUtf8Bytes("keymaterial"), generationId);
mRecoverableKeyStoreDb.insertKey(
- /*userId=*/ 1, /*alias=*/ "test", wrappedKey, generationId);
+ /*userId=*/ 1, /*alias=*/ "test", wrappedKey);
Map<String, WrappedKey> keys = mRecoverableKeyStoreDb.getAllKeys(
/*userId=*/ 2, generationId);
diff --git a/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
index 7f48b8e..0c35fcb 100644
--- a/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
@@ -19,7 +19,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import com.android.frameworks.servicestests.R;
import com.android.servicestests.aidl.ICmdReceiverService;
@@ -42,6 +41,7 @@
import android.util.Log;
import org.junit.AfterClass;
+import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -81,7 +81,7 @@
private static final long NETWORK_CHECK_TIMEOUT_MS = 4000; // 4 sec
- private static final long SCREEN_ON_DELAY_MS = 500; // 0.5 sec
+ private static final long SCREEN_ON_DELAY_MS = 1000; // 1 sec
private static final long BIND_SERVICE_TIMEOUT_SEC = 4;
@@ -348,13 +348,17 @@
}
private String executeCommand(String cmd) throws IOException {
- final String result = mUiDevice.executeShellCommand(cmd).trim();
+ final String result = executeSilentCommand(cmd);
Log.d(TAG, String.format("Result for '%s': %s", cmd, result));
return result;
}
+ private static String executeSilentCommand(String cmd) throws IOException {
+ return mUiDevice.executeShellCommand(cmd).trim();
+ }
+
private void assertDelayedCommandResult(String cmd, String expectedResult,
- int maxTries, int napTimeMs) throws IOException {
+ int maxTries, int napTimeMs) throws Exception {
String result = "";
for (int i = 1; i <= maxTries; ++i) {
result = executeCommand(cmd);
@@ -394,6 +398,23 @@
}
}
+ private static void fail(String msg) throws Exception {
+ dumpOnFailure();
+ Assert.fail(msg);
+ }
+
+ private static void dumpOnFailure() throws Exception {
+ Log.d(TAG, ">>> Begin network_management dump");
+ Log.printlns(Log.LOG_ID_MAIN, Log.DEBUG,
+ TAG, executeSilentCommand("dumpsys network_management"), null);
+ Log.d(TAG, "<<< End network_management dump");
+
+ Log.d(TAG, ">>> Begin netpolicy dump");
+ Log.printlns(Log.LOG_ID_MAIN, Log.DEBUG,
+ TAG, executeSilentCommand("dumpsys netpolicy"), null);
+ Log.d(TAG, "<<< End netpolicy dump");
+ }
+
private void finishActivity() throws Exception {
mCmdReceiverService.finishActivity();
}
diff --git a/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java b/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java
index b26cc7fd..f8d1d03 100644
--- a/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java
+++ b/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java
@@ -77,6 +77,7 @@
Log.i(TAG, "onStop called");
if (finishCommandReceiver != null) {
unregisterReceiver(finishCommandReceiver);
+ finishCommandReceiver = null;
}
super.onStop();
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 07c860b..cdce448 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -495,8 +495,8 @@
flushToDiskLocked();
pw.println("Flushed stats to disk");
return;
- } else {
- // Anything else is a pkg to filter
+ } else if (arg != null && !arg.startsWith("-")) {
+ // Anything else that doesn't start with '-' is a pkg to filter
pkg = arg;
break;
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index dedce17..6a47d05 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1717,6 +1717,13 @@
public static final String KEY_SPN_DISPLAY_RULE_USE_ROAMING_FROM_SERVICE_STATE_BOOL =
"spn_display_rule_use_roaming_from_service_state_bool";
+ /**
+ * Determines whether any carrier has been identified and its specific config has been applied,
+ * default to false.
+ * @hide
+ */
+ public static final String KEY_CARRIER_CONFIG_APPLIED_BOOL = "carrier_config_applied_bool";
+
/** The default value for every variable. */
private final static PersistableBundle sDefaults;
@@ -2002,6 +2009,7 @@
sDefaults.putBoolean(KEY_IDENTIFY_HIGH_DEFINITION_CALLS_IN_CALL_LOG_BOOL, false);
sDefaults.putBoolean(KEY_SPN_DISPLAY_RULE_USE_ROAMING_FROM_SERVICE_STATE_BOOL, false);
sDefaults.putBoolean(KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL, false);
+ sDefaults.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
}
/**
@@ -2047,6 +2055,33 @@
}
/**
+ * Determines whether a configuration {@link PersistableBundle} obtained from
+ * {@link #getConfig()} or {@link #getConfigForSubId(int)} corresponds to an identified carrier.
+ * <p>
+ * When an app receives the {@link CarrierConfigManager#ACTION_CARRIER_CONFIG_CHANGED}
+ * broadcast which informs it that the carrier configuration has changed, it is possible
+ * that another reload of the carrier configuration has begun since the intent was sent.
+ * In this case, the carrier configuration the app fetches (e.g. via {@link #getConfig()})
+ * may not represent the configuration for the current carrier. It should be noted that it
+ * does not necessarily mean the configuration belongs to current carrier when this function
+ * return true because it may belong to another previous identified carrier. Users should
+ * always call {@link #getConfig()} or {@link #getConfigForSubId(int)} after receiving the
+ * broadcast {@link #ACTION_CARRIER_CONFIG_CHANGED}.
+ * </p>
+ * <p>
+ * After using {@link #getConfig()} or {@link #getConfigForSubId(int)} an app should always
+ * use this method to confirm whether any carrier specific configuration has been applied.
+ * </p>
+ *
+ * @param bundle the configuration bundle to be checked.
+ * @return boolean true if any carrier specific configuration bundle has been applied, false
+ * otherwise or the bundle is null.
+ */
+ public static boolean isConfigForIdentifiedCarrier(PersistableBundle bundle) {
+ return bundle != null && bundle.getBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL);
+ }
+
+ /**
* Calling this method triggers telephony services to fetch the current carrier configuration.
* <p>
* Normally this does not need to be called because the platform reloads config on its own.
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index 710eff0..a6dbc06 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -19,6 +19,7 @@
import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
import android.annotation.StringDef;
+import android.app.PendingIntent;
import android.content.res.Resources;
import android.os.Binder;
import android.text.TextUtils;
@@ -92,11 +93,13 @@
/**
* Indicates a 3GPP format SMS message.
+ * @see SmsManager#injectSmsPdu(byte[], String, PendingIntent)
*/
public static final String FORMAT_3GPP = "3gpp";
/**
* Indicates a 3GPP2 format SMS message.
+ * @see SmsManager#injectSmsPdu(byte[], String, PendingIntent)
*/
public static final String FORMAT_3GPP2 = "3gpp2";
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 28ae10b..93c0c51 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5747,39 +5747,38 @@
* @param enable Whether to enable mobile data.
*
* @see #hasCarrierPrivileges
+ * @deprecated use {@link #setUserMobileDataEnabled(boolean)} instead.
*/
+ @Deprecated
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void setDataEnabled(boolean enable) {
- setDataEnabled(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), enable);
+ setUserMobileDataEnabled(enable);
}
- /** @hide */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- public void setDataEnabled(int subId, boolean enable) {
- try {
- Log.d(TAG, "setDataEnabled: enabled=" + enable);
- ITelephony telephony = getITelephony();
- if (telephony != null)
- telephony.setDataEnabled(subId, enable);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#setDataEnabled", e);
- }
- }
-
-
/**
- * @deprecated use {@link #isDataEnabled()} instead.
+ * @hide
+ * @deprecated use {@link #setUserMobileDataEnabled(boolean)} instead.
+ */
+ @SystemApi
+ @Deprecated
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public void setDataEnabled(int subId, boolean enable) {
+ setUserMobileDataEnabled(subId, enable);
+ }
+
+ /**
+ * @deprecated use {@link #isUserMobileDataEnabled()} instead.
* @hide
*/
@SystemApi
@Deprecated
public boolean getDataEnabled() {
- return isDataEnabled();
+ return isUserMobileDataEnabled();
}
/**
- * Returns whether mobile data is enabled or not.
+ * Returns whether mobile data is enabled or not per user setting. There are other factors
+ * that could disable mobile data, but they are not considered here.
*
* If this object has been created with {@link #createForSubscriptionId}, applies to the given
* subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
@@ -5796,28 +5795,21 @@
* @return true if mobile data is enabled.
*
* @see #hasCarrierPrivileges
+ * @deprecated use {@link #isUserMobileDataEnabled()} instead.
*/
- @SuppressWarnings("deprecation")
+ @Deprecated
public boolean isDataEnabled() {
- return getDataEnabled(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
+ return isUserMobileDataEnabled();
}
/**
- * @deprecated use {@link #isDataEnabled(int)} instead.
+ * @deprecated use {@link #isUserMobileDataEnabled()} instead.
* @hide
*/
+ @Deprecated
@SystemApi
public boolean getDataEnabled(int subId) {
- boolean retVal = false;
- try {
- ITelephony telephony = getITelephony();
- if (telephony != null)
- retVal = telephony.getDataEnabled(subId);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#getDataEnabled", e);
- } catch (NullPointerException e) {
- }
- return retVal;
+ return isUserMobileDataEnabled(subId);
}
/** @hide */
@@ -7021,4 +7013,101 @@
}
return null;
}
+
+ /**
+ * Turns mobile data on or off.
+ * If the {@link TelephonyManager} object has been created with
+ * {@link #createForSubscriptionId}, this API applies to the given subId.
+ * Otherwise, it applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the
+ * calling app has carrier privileges.
+ *
+ * @param enable Whether to enable mobile data.
+ *
+ * @see #hasCarrierPrivileges
+ */
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public void setUserMobileDataEnabled(boolean enable) {
+ setUserMobileDataEnabled(
+ getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), enable);
+ }
+
+ /**
+ * Returns whether mobile data is enabled or not per user setting. There are other factors
+ * that could disable mobile data, but they are not considered here.
+ *
+ * If this object has been created with {@link #createForSubscriptionId}, applies to the given
+ * subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+ *
+ * <p>Requires one of the following permissions:
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE ACCESS_NETWORK_STATE},
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}, or that the
+ * calling app has carrier privileges.
+ *
+ * <p>Note that this does not take into account any data restrictions that may be present on the
+ * calling app. Such restrictions may be inspected with
+ * {@link ConnectivityManager#getRestrictBackgroundStatus}.
+ *
+ * @return true if mobile data is enabled.
+ *
+ * @see #hasCarrierPrivileges
+ */
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_NETWORK_STATE,
+ android.Manifest.permission.MODIFY_PHONE_STATE
+ })
+ public boolean isUserMobileDataEnabled() {
+ return isUserMobileDataEnabled(
+ getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
+ }
+
+ /**
+ * @hide
+ * Unlike isUserMobileDataEnabled, this API also evaluates carrierDataEnabled,
+ * policyDataEnabled etc to give a final decision.
+ */
+ public boolean isMobileDataEnabled() {
+ boolean retVal = false;
+ try {
+ int subId = getSubId(SubscriptionManager.getDefaultDataSubscriptionId());
+ ITelephony telephony = getITelephony();
+ if (telephony != null)
+ retVal = telephony.isDataEnabled(subId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#isDataEnabled", e);
+ } catch (NullPointerException e) {
+ }
+ return retVal;
+ }
+
+ /**
+ * Utility class of {@link #isUserMobileDataEnabled()};
+ */
+ private boolean isUserMobileDataEnabled(int subId) {
+ boolean retVal = false;
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null)
+ retVal = telephony.isUserDataEnabled(subId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#isUserDataEnabled", e);
+ } catch (NullPointerException e) {
+ }
+ return retVal;
+ }
+
+ /** Utility method of {@link #setUserMobileDataEnabled(boolean)} */
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ private void setUserMobileDataEnabled(int subId, boolean enable) {
+ try {
+ Log.d(TAG, "setUserMobileDataEnabled: enabled=" + enable);
+ ITelephony telephony = getITelephony();
+ if (telephony != null)
+ telephony.setUserDataEnabled(subId, enable);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#setUserDataEnabled", e);
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index a9f8f45..8ea53a5 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -870,14 +870,33 @@
*
* @param enable true to turn on, else false
*/
- void setDataEnabled(int subId, boolean enable);
+ void setUserDataEnabled(int subId, boolean enable);
+
+ /**
+ * Get the user enabled state of Mobile Data.
+ *
+ * TODO: remove and use isUserDataEnabled.
+ * This can't be removed now because some vendor codes
+ * calls through ITelephony directly while they should
+ * use TelephonyManager.
+ *
+ * @return true on enabled
+ */
+ boolean getDataEnabled(int subId);
/**
* Get the user enabled state of Mobile Data.
*
* @return true on enabled
*/
- boolean getDataEnabled(int subId);
+ boolean isUserDataEnabled(int subId);
+
+ /**
+ * Get the overall enabled state of Mobile Data.
+ *
+ * @return true on enabled
+ */
+ boolean isDataEnabled(int subId);
/**
* Get P-CSCF address from PCO after data connection is established or modified.
diff --git a/tests/Internal/Android.mk b/tests/Internal/Android.mk
index 73181ec..b69e3e4 100644
--- a/tests/Internal/Android.mk
+++ b/tests/Internal/Android.mk
@@ -14,6 +14,7 @@
android-support-test \
mockito-target-minus-junit4
+LOCAL_JAVA_RESOURCE_DIRS := res
LOCAL_CERTIFICATE := platform
LOCAL_PACKAGE_NAME := InternalTests
diff --git a/tests/Internal/AndroidManifest.xml b/tests/Internal/AndroidManifest.xml
index a2c95fb..e5a5694 100644
--- a/tests/Internal/AndroidManifest.xml
+++ b/tests/Internal/AndroidManifest.xml
@@ -18,8 +18,24 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.internal.tests">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.BIND_WALLPAPER" />
<application>
<uses-library android:name="android.test.runner" />
+
+ <service android:name="stub.DummyWallpaperService"
+ android:enabled="true"
+ android:directBootAware="true"
+ android:label="Dummy wallpaper"
+ android:permission="android.permission.BIND_WALLPAPER">
+
+ <intent-filter>
+ <action android:name="android.service.wallpaper.WallpaperService" />
+ </intent-filter>
+
+ <!-- Link to XML that defines the wallpaper info. -->
+ <meta-data android:name="android.service.wallpaper"
+ android:resource="@xml/livewallpaper" />
+ </service>
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/Internal/res/xml/livewallpaper.xml b/tests/Internal/res/xml/livewallpaper.xml
new file mode 100644
index 0000000..dbb0e47
--- /dev/null
+++ b/tests/Internal/res/xml/livewallpaper.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2017 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<wallpaper
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ androidprv:supportsAmbientMode="true"/>
\ No newline at end of file
diff --git a/tests/Internal/src/android/app/WallpaperInfoTest.java b/tests/Internal/src/android/app/WallpaperInfoTest.java
new file mode 100644
index 0000000..9d26270
--- /dev/null
+++ b/tests/Internal/src/android/app/WallpaperInfoTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Parcel;
+import android.service.wallpaper.WallpaperService;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+/**
+ * Tests for hidden WallpaperInfo methods.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class WallpaperInfoTest {
+
+ @Test
+ public void testSupportsAmbientMode() throws Exception {
+ Context context = InstrumentationRegistry.getTargetContext();
+
+ Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
+ intent.setPackage("com.android.internal.tests");
+ PackageManager pm = context.getPackageManager();
+ List<ResolveInfo> result = pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
+ assertEquals(1, result.size());
+ ResolveInfo info = result.get(0);
+ WallpaperInfo wallpaperInfo = new WallpaperInfo(context, info);
+
+ // Defined as true in the XML
+ assertTrue("supportsAmbientMode should be true, as defined in the XML.",
+ wallpaperInfo.getSupportsAmbientMode());
+ Parcel parcel = Parcel.obtain();
+ wallpaperInfo.writeToParcel(parcel, 0 /* flags */);
+ parcel.setDataPosition(0);
+ WallpaperInfo fromParcel = WallpaperInfo.CREATOR.createFromParcel(parcel);
+ assertTrue("supportsAmbientMode should have been restored from parcelable",
+ fromParcel.getSupportsAmbientMode());
+ parcel.recycle();
+ }
+}
+
diff --git a/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java b/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java
new file mode 100644
index 0000000..f7ce2c7
--- /dev/null
+++ b/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.wallpaper;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@SmallTest
+@RunWith(JUnit4.class)
+public class WallpaperServiceTest {
+
+ @Test
+ public void testDeliversAmbientModeChanged() {
+ int[] ambientModeChangedCount = {0};
+ WallpaperService service = new WallpaperService() {
+ @Override
+ public Engine onCreateEngine() {
+ return new Engine() {
+ @Override
+ public void onAmbientModeChanged(boolean inAmbientMode) {
+ ambientModeChangedCount[0]++;
+ }
+ };
+ }
+ };
+ WallpaperService.Engine engine = service.onCreateEngine();
+ engine.setCreated(true);
+
+ engine.doAmbientModeChanged(false);
+ assertFalse("ambient mode should be false", engine.isInAmbientMode());
+ assertEquals("onAmbientModeChanged should have been called",
+ ambientModeChangedCount[0], 1);
+
+ engine.doAmbientModeChanged(true);
+ assertTrue("ambient mode should be false", engine.isInAmbientMode());
+ assertEquals("onAmbientModeChanged should have been called",
+ ambientModeChangedCount[0], 2);
+ }
+
+}
diff --git a/tests/Internal/src/stub/DummyWallpaperService.java b/tests/Internal/src/stub/DummyWallpaperService.java
new file mode 100644
index 0000000..084c036
--- /dev/null
+++ b/tests/Internal/src/stub/DummyWallpaperService.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 stub;
+
+import android.service.wallpaper.WallpaperService;
+
+/**
+ * Dummy wallpaper service only for test purposes, won't draw anything.
+ */
+public class DummyWallpaperService extends WallpaperService {
+ @Override
+ public Engine onCreateEngine() {
+ return new Engine();
+ }
+}
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index 8683c12..f38a9a3 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -27,6 +27,7 @@
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -40,10 +41,14 @@
import android.net.IpSecUdpEncapResponse;
import android.os.Binder;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.system.ErrnoException;
import android.system.Os;
+import android.system.StructStat;
+
+import dalvik.system.SocketTagger;
import java.io.FileDescriptor;
import java.net.InetAddress;
@@ -56,6 +61,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
/** Unit tests for {@link IpSecService}. */
@SmallTest
@@ -411,4 +417,62 @@
mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId);
}
}
+
+ @Test
+ public void testUidFdtagger() throws Exception {
+ SocketTagger actualSocketTagger = SocketTagger.get();
+
+ try {
+ FileDescriptor sockFd = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+ // Has to be done after socket creation because BlockGuardOS calls tag on new sockets
+ SocketTagger mockSocketTagger = mock(SocketTagger.class);
+ SocketTagger.set(mockSocketTagger);
+
+ mIpSecService.mUidFdTagger.tag(sockFd, Process.LAST_APPLICATION_UID);
+ verify(mockSocketTagger).tag(eq(sockFd));
+ } finally {
+ SocketTagger.set(actualSocketTagger);
+ }
+ }
+
+ /**
+ * Checks if two file descriptors point to the same file.
+ *
+ * <p>According to stat.h documentation, the correct way to check for equivalent or duplicated
+ * file descriptors is to check their inode and device. These two entries uniquely identify any
+ * file.
+ */
+ private boolean fileDescriptorsEqual(FileDescriptor fd1, FileDescriptor fd2) {
+ try {
+ StructStat fd1Stat = Os.fstat(fd1);
+ StructStat fd2Stat = Os.fstat(fd2);
+
+ return fd1Stat.st_ino == fd2Stat.st_ino && fd1Stat.st_dev == fd2Stat.st_dev;
+ } catch (ErrnoException e) {
+ return false;
+ }
+ }
+
+ @Test
+ public void testOpenUdpEncapSocketTagsSocket() throws Exception {
+ IpSecService.UidFdTagger mockTagger = mock(IpSecService.UidFdTagger.class);
+ IpSecService testIpSecService =
+ new IpSecService(mMockContext, mMockIpSecSrvConfig, mockTagger);
+
+ IpSecUdpEncapResponse udpEncapResp =
+ testIpSecService.openUdpEncapsulationSocket(0, new Binder());
+ assertNotNull(udpEncapResp);
+ assertEquals(IpSecManager.Status.OK, udpEncapResp.status);
+
+ FileDescriptor sockFd = udpEncapResp.fileDescriptor.getFileDescriptor();
+ ArgumentMatcher<FileDescriptor> fdMatcher =
+ (argFd) -> {
+ return fileDescriptorsEqual(sockFd, argFd);
+ };
+ verify(mockTagger).tag(argThat(fdMatcher), eq(Os.getuid()));
+
+ testIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId);
+ udpEncapResp.fileDescriptor.close();
+ }
}
diff --git a/tools/streaming_proto/Android.bp b/tools/streaming_proto/Android.bp
index 4e9391d..1121ead 100644
--- a/tools/streaming_proto/Android.bp
+++ b/tools/streaming_proto/Android.bp
@@ -32,26 +32,6 @@
shared_libs: ["libprotoc"],
}
-cc_library {
- name: "streamingflags",
- host_supported: true,
- proto: {
- export_proto_headers: true,
- include_dirs: ["external/protobuf/src"],
- },
-
- target: {
- host: {
- proto: {
- type: "full",
- },
- srcs: [
- "stream.proto",
- ],
- },
- },
-}
-
cc_binary_host {
name: "protoc-gen-javastream",
srcs: [
@@ -68,5 +48,4 @@
],
defaults: ["protoc-gen-stream-defaults"],
- static_libs: ["streamingflags"],
}
diff --git a/tools/streaming_proto/cpp/main.cpp b/tools/streaming_proto/cpp/main.cpp
index 745b3dc..d6b9d81 100644
--- a/tools/streaming_proto/cpp/main.cpp
+++ b/tools/streaming_proto/cpp/main.cpp
@@ -2,8 +2,6 @@
#include "stream_proto_utils.h"
#include "string_utils.h"
-#include <frameworks/base/tools/streaming_proto/stream.pb.h>
-
#include <iomanip>
#include <iostream>
#include <sstream>
@@ -12,18 +10,14 @@
using namespace google::protobuf::io;
using namespace std;
+const bool GENERATE_MAPPING = true;
+
static string
make_filename(const FileDescriptorProto& file_descriptor)
{
return file_descriptor.name() + ".h";
}
-static inline bool
-should_generate_enums_mapping(const EnumDescriptorProto& enu)
-{
- return enu.options().GetExtension(stream_enum).enable_enums_mapping();
-}
-
static void
write_enum(stringstream& text, const EnumDescriptorProto& enu, const string& indent)
{
@@ -36,7 +30,7 @@
<< " = " << value.number() << ";" << endl;
}
- if (should_generate_enums_mapping(enu)) {
+ if (GENERATE_MAPPING) {
string name = make_constant_name(enu.name());
string prefix = name + "_";
text << indent << "const int _ENUM_" << name << "_COUNT = " << N << ";" << endl;
@@ -79,23 +73,11 @@
text << endl;
}
-static inline bool
-should_generate_fields_mapping(const DescriptorProto& message)
-{
- return message.options().GetExtension(stream_msg).enable_fields_mapping();
-}
-
-static inline bool
-should_generate_fields_mapping_recursively(const DescriptorProto& message) {
- return message.options().GetExtension(stream_msg).enable_fields_mapping_recursively();
-}
-
static void
-write_message(stringstream& text, const DescriptorProto& message, const string& indent, bool genMapping)
+write_message(stringstream& text, const DescriptorProto& message, const string& indent)
{
int N;
const string indented = indent + INDENT;
- genMapping |= should_generate_fields_mapping_recursively(message);
text << indent << "// message " << message.name() << endl;
text << indent << "namespace " << message.name() << " {" << endl;
@@ -109,7 +91,7 @@
// Nested classes
N = message.nested_type_size();
for (int i=0; i<N; i++) {
- write_message(text, message.nested_type(i), indented, genMapping);
+ write_message(text, message.nested_type(i), indented);
}
// Fields
@@ -118,7 +100,7 @@
write_field(text, message.field(i), indented);
}
- if (genMapping | should_generate_fields_mapping(message)) {
+ if (GENERATE_MAPPING) {
N = message.field_size();
text << indented << "const int _FIELD_COUNT = " << N << ";" << endl;
text << indented << "const char* _FIELD_NAMES[" << N << "] = {" << endl;
@@ -167,7 +149,7 @@
N = file_descriptor.message_type_size();
for (size_t i=0; i<N; i++) {
- write_message(text, file_descriptor.message_type(i), "", false);
+ write_message(text, file_descriptor.message_type(i), "");
}
for (vector<string>::iterator it = namespaces.begin(); it != namespaces.end(); it++) {
diff --git a/tools/streaming_proto/stream.proto b/tools/streaming_proto/stream.proto
deleted file mode 100644
index e9b24a8..0000000
--- a/tools/streaming_proto/stream.proto
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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";
-
-import "google/protobuf/descriptor.proto";
-
-package android.stream_proto;
-
-// This option tells streaming proto plugin to compile .proto files with extra features.
-message MessageOptions {
- // creates a mapping of field names of the message to its field ids
- optional bool enable_fields_mapping = 1;
-
- // creates mapping between field names to its field ids and recursively for its submessages.
- optional bool enable_fields_mapping_recursively = 2;
-}
-
-extend google.protobuf.MessageOptions {
- // Flags used by streaming proto plugins
- optional MessageOptions stream_msg = 126856794;
-}
-
-message EnumOptions {
- // creates a mapping of enum names to its values, strip its prefix enum type for each value
- optional bool enable_enums_mapping = 1;
-}
-
-extend google.protobuf.EnumOptions {
- // Flags used by streaming proto plugins
- optional EnumOptions stream_enum = 126856794;
-}